diff --git a/ecc/bls12-377/fr/mimc/doc.go b/ecc/bls12-377/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bls12-377/fr/mimc/doc.go +++ b/ecc/bls12-377/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bls12-378/fr/mimc/doc.go b/ecc/bls12-378/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bls12-378/fr/mimc/doc.go +++ b/ecc/bls12-378/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bls12-381/fr/mimc/doc.go b/ecc/bls12-381/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bls12-381/fr/mimc/doc.go +++ b/ecc/bls12-381/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bls24-315/fr/mimc/doc.go b/ecc/bls24-315/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bls24-315/fr/mimc/doc.go +++ b/ecc/bls24-315/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bls24-317/fr/mimc/doc.go b/ecc/bls24-317/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bls24-317/fr/mimc/doc.go +++ b/ecc/bls24-317/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bn254/fr/mimc/doc.go b/ecc/bn254/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bn254/fr/mimc/doc.go +++ b/ecc/bn254/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bw6-633/fr/mimc/doc.go b/ecc/bw6-633/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bw6-633/fr/mimc/doc.go +++ b/ecc/bw6-633/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bw6-756/fr/mimc/doc.go b/ecc/bw6-756/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bw6-756/fr/mimc/doc.go +++ b/ecc/bw6-756/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/ecc/bw6-761/fr/mimc/doc.go b/ecc/bw6-761/fr/mimc/doc.go index d527ead9e..78837e1c8 100644 --- a/ecc/bw6-761/fr/mimc/doc.go +++ b/ecc/bw6-761/fr/mimc/doc.go @@ -15,4 +15,46 @@ // Code generated by consensys/gnark-crypto DO NOT EDIT // Package mimc provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package mimc diff --git a/hash/doc.go b/hash/doc.go new file mode 100644 index 000000000..faefa0669 --- /dev/null +++ b/hash/doc.go @@ -0,0 +1,48 @@ +// Package hash provides MiMC hash function defined over implemented curves +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. +// +// See open issues: +// - https://github.com/Consensys/gnark-crypto/issues/504 +// - https://github.com/Consensys/gnark-crypto/issues/485 +package hash diff --git a/hash/hashes.go b/hash/hashes.go index 37bce2959..8f668c7a4 100644 --- a/hash/hashes.go +++ b/hash/hashes.go @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package hash provides MiMC hash function defined over curves implemented in gnark-crypto/ecc. -// -// Originally developed and used in a ZKP context. package hash import ( @@ -31,17 +28,27 @@ import ( bw761 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/mimc" ) +// Hash defines an unique identifier for a hash function. type Hash uint const ( + // MIMC_BN254 is the MiMC hash function for the BN254 curve. MIMC_BN254 Hash = iota + // MIMC_BLS12_381 is the MiMC hash function for the BLS12-381 curve. MIMC_BLS12_381 + // MIMC_BLS12_377 is the MiMC hash function for the BLS12-377 curve. MIMC_BLS12_377 + // MIMC_BLS12_378 is the MiMC hash function for the BLS12-378 curve. MIMC_BLS12_378 + // MIMC_BW6_761 is the MiMC hash function for the BW6-761 curve. MIMC_BW6_761 + // MIMC_BLS24_315 is the MiMC hash function for the BLS24-315 curve. MIMC_BLS24_315 + // MIMC_BLS24_317 is the MiMC hash function for the BLS24-317 curve. MIMC_BLS24_317 + // MIMC_BW6_633 is the MiMC hash function for the BW6-633 curve. MIMC_BW6_633 + // MIMC_BW6_756 is the MiMC hash function for the BW6-756 curve. MIMC_BW6_756 ) @@ -58,7 +65,7 @@ var digestSize = []uint8{ MIMC_BW6_756: 96, } -// New creates the corresponding mimc hash function. +// New initializes the hash function. func (m Hash) New() hash.Hash { switch m { case MIMC_BN254: @@ -84,7 +91,7 @@ func (m Hash) New() hash.Hash { } } -// String returns the mimc ID to string format. +// String returns the unique identifier of the hash function. func (m Hash) String() string { switch m { case MIMC_BN254: diff --git a/internal/generator/crypto/hash/mimc/template/doc.go.tmpl b/internal/generator/crypto/hash/mimc/template/doc.go.tmpl index 6e02e3787..38175ffd9 100644 --- a/internal/generator/crypto/hash/mimc/template/doc.go.tmpl +++ b/internal/generator/crypto/hash/mimc/template/doc.go.tmpl @@ -1,2 +1,44 @@ // Package {{.Package}} provides MiMC hash function using Miyaguchi–Preneel construction. +// +// # Length extension attack +// +// The MiMC hash function is vulnerable to a length extension attack. For +// example when we have a hash +// +// h = MiMC(k || m) +// +// and we want to hash a new message +// +// m' = m || m2, +// +// we can compute +// +// h' = MiMC(k || m || m2) +// +// without knowing k by computing +// +// h' = MiMC(h || m2). +// +// This is because the MiMC hash function is a simple iterated cipher, and the +// hash value is the state of the cipher after encrypting the message. +// +// There are several ways to mitigate this attack: +// - use a random key for each hash +// - use a domain separation tag for different use cases: +// h = MiMC(k || tag || m) +// - use the secret input as last input: +// h = MiMC(m || k) +// +// In general, inside a circuit the length-extension attack is not a concern as +// due to the circuit definition the attacker can not append messages to +// existing hash. But the user has to consider the cases when using a secret key +// and MiMC in different contexts. +// +// # Hash input format +// +// The MiMC hash function is defined over a field. The input to the hash +// function is a byte slice. The byte slice is interpreted as a sequence of +// field elements. Due to this interpretation, the input byte slice length must +// be multiple of the field modulus size. And every secuence of byte slice for a +// single field element must be strictly less than the field modulus. package {{.Package}} \ No newline at end of file