refactor hash implementations with hash_to_array/scalar functions
This commit is contained in:
parent
8a391caab8
commit
2967cae5e4
|
@ -9,7 +9,7 @@ use curve25519_dalek::{
|
|||
traits::Identity,
|
||||
};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use sha2::{digest::Update, Digest, Sha512};
|
||||
use sha2::{Digest, Sha512};
|
||||
|
||||
use frost_core::{frost, Ciphersuite, Field, Group, GroupError};
|
||||
|
||||
|
@ -65,6 +65,21 @@ impl Group for Ed25519Group {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_to_array(inputs: &[&[u8]]) -> [u8; 64] {
|
||||
let mut h = Sha512::new();
|
||||
for i in inputs {
|
||||
h.update(i);
|
||||
}
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
}
|
||||
|
||||
fn hash_to_scalar(inputs: &[&[u8]]) -> Scalar {
|
||||
let output = hash_to_array(inputs);
|
||||
Scalar::from_bytes_mod_order_wide(&output)
|
||||
}
|
||||
|
||||
/// Context string 'FROST-RISTRETTO255-SHA512-v5' from the ciphersuite in the [spec]
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-1
|
||||
|
@ -85,79 +100,40 @@ impl Ciphersuite for Ed25519Sha512 {
|
|||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-2.2.2.1
|
||||
fn H1(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("rho")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"rho", m])
|
||||
}
|
||||
|
||||
/// H2 for FROST(Ed25519, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-2.2.2.2
|
||||
fn H2(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new().chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[m])
|
||||
}
|
||||
|
||||
/// H3 for FROST(Ed25519, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-2.2.2.3
|
||||
fn H3(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("nonce")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"nonce", m])
|
||||
}
|
||||
|
||||
/// H4 for FROST(Ed25519, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-2.2.2.4
|
||||
fn H4(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("msg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"msg", m])
|
||||
}
|
||||
|
||||
/// H5 for FROST(Ed25519, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.1-2.2.2.5
|
||||
fn H5(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("com")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"com", m])
|
||||
}
|
||||
|
||||
/// HDKG for FROST(Ed25519, SHA-512)
|
||||
fn HDKG(m: &[u8]) -> Option<<<Self::Group as Group>::Field as Field>::Scalar> {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("dkg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
Some(<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output))
|
||||
Some(hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"dkg", m]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use p256::{
|
|||
AffinePoint, ProjectivePoint, Scalar,
|
||||
};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use sha2::{digest::Update, Digest, Sha256};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use frost_core::{frost, Ciphersuite, Field, FieldError, Group, GroupError};
|
||||
|
||||
|
@ -140,6 +140,23 @@ impl Group for P256Group {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_to_array(inputs: &[&[u8]]) -> [u8; 32] {
|
||||
let mut h = Sha256::new();
|
||||
for i in inputs {
|
||||
h.update(i);
|
||||
}
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
}
|
||||
|
||||
fn hash_to_scalar(domain: &[u8], msg: &[u8]) -> Scalar {
|
||||
let mut u = [P256ScalarField::zero()];
|
||||
hash_to_field::<ExpandMsgXmd<Sha256>, Scalar>(&[msg], domain, &mut u)
|
||||
.expect("should never return error according to error cases described in ExpandMsgXmd");
|
||||
u[0]
|
||||
}
|
||||
|
||||
/// Context string from the ciphersuite in the [spec]
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-1
|
||||
|
@ -160,70 +177,43 @@ impl Ciphersuite for P256Sha256 {
|
|||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-2.2.2.1
|
||||
fn H1(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let mut u = [P256ScalarField::zero()];
|
||||
let dst = CONTEXT_STRING.to_owned() + "rho";
|
||||
hash_to_field::<ExpandMsgXmd<Sha256>, Scalar>(&[m], dst.as_bytes(), &mut u)
|
||||
.expect("should never return error according to error cases described in ExpandMsgXmd");
|
||||
u[0]
|
||||
hash_to_scalar((CONTEXT_STRING.to_owned() + "rho").as_bytes(), m)
|
||||
}
|
||||
|
||||
/// H2 for FROST(P-256, SHA-256)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-2.2.2.2
|
||||
fn H2(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let mut u = [P256ScalarField::zero()];
|
||||
let dst = CONTEXT_STRING.to_owned() + "chal";
|
||||
hash_to_field::<ExpandMsgXmd<Sha256>, Scalar>(&[m], dst.as_bytes(), &mut u)
|
||||
.expect("should never return error according to error cases described in ExpandMsgXmd");
|
||||
u[0]
|
||||
hash_to_scalar((CONTEXT_STRING.to_owned() + "chal").as_bytes(), m)
|
||||
}
|
||||
|
||||
/// H3 for FROST(P-256, SHA-256)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-2.2.2.3
|
||||
fn H3(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let mut u = [P256ScalarField::zero()];
|
||||
let dst = CONTEXT_STRING.to_owned() + "nonce";
|
||||
hash_to_field::<ExpandMsgXmd<Sha256>, Scalar>(&[m], dst.as_bytes(), &mut u)
|
||||
.expect("should never return error according to error cases described in ExpandMsgXmd");
|
||||
u[0]
|
||||
hash_to_scalar((CONTEXT_STRING.to_owned() + "nonce").as_bytes(), m)
|
||||
}
|
||||
|
||||
/// H4 for FROST(P-256, SHA-256)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-2.2.2.4
|
||||
fn H4(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha256::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("msg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"msg", m])
|
||||
}
|
||||
|
||||
/// H5 for FROST(P-256, SHA-256)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.4-2.2.2.5
|
||||
fn H5(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha256::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("com")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"com", m])
|
||||
}
|
||||
|
||||
/// HDKG for FROST(P-256, SHA-256)
|
||||
fn HDKG(m: &[u8]) -> Option<<<Self::Group as Group>::Field as Field>::Scalar> {
|
||||
let mut u = [P256ScalarField::zero()];
|
||||
let dst = CONTEXT_STRING.to_owned() + "dkg";
|
||||
hash_to_field::<ExpandMsgXmd<Sha256>, Scalar>(&[m], dst.as_bytes(), &mut u)
|
||||
.expect("should never return error according to error cases described in ExpandMsgXmd");
|
||||
Some(u[0])
|
||||
Some(hash_to_scalar(
|
||||
(CONTEXT_STRING.to_owned() + "dkg").as_bytes(),
|
||||
m,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use curve25519_dalek::{
|
|||
traits::Identity,
|
||||
};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use sha2::{digest::Update, Digest, Sha512};
|
||||
use sha2::{Digest, Sha512};
|
||||
|
||||
use frost_core::{frost, Ciphersuite, Field, FieldError, Group, GroupError};
|
||||
|
||||
|
@ -107,6 +107,21 @@ impl Group for RistrettoGroup {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_to_array(inputs: &[&[u8]]) -> [u8; 64] {
|
||||
let mut h = Sha512::new();
|
||||
for i in inputs {
|
||||
h.update(i);
|
||||
}
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
}
|
||||
|
||||
fn hash_to_scalar(inputs: &[&[u8]]) -> Scalar {
|
||||
let output = hash_to_array(inputs);
|
||||
Scalar::from_bytes_mod_order_wide(&output)
|
||||
}
|
||||
|
||||
/// Context string from the ciphersuite in the [spec].
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-1
|
||||
|
@ -127,82 +142,40 @@ impl Ciphersuite for Ristretto255Sha512 {
|
|||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-2.2.2.1
|
||||
fn H1(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("rho")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"rho", m])
|
||||
}
|
||||
|
||||
/// H2 for FROST(ristretto255, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-2.2.2.2
|
||||
fn H2(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("chal")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"chal", m])
|
||||
}
|
||||
|
||||
/// H3 for FROST(ristretto255, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-2.2.2.3
|
||||
fn H3(m: &[u8]) -> <<Self::Group as Group>::Field as Field>::Scalar {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("nonce")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output)
|
||||
hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"nonce", m])
|
||||
}
|
||||
|
||||
/// H4 for FROST(ristretto255, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-2.2.2.4
|
||||
fn H4(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("msg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"msg", m])
|
||||
}
|
||||
|
||||
/// H5 for FROST(ristretto255, SHA-512)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.2-2.2.2.5
|
||||
fn H5(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("com")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"com", m])
|
||||
}
|
||||
|
||||
/// HDKG for FROST(ristretto255, SHA-512)
|
||||
fn HDKG(m: &[u8]) -> Option<<<Self::Group as Group>::Field as Field>::Scalar> {
|
||||
let h = Sha512::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("dkg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 64];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
Some(<<Self::Group as Group>::Field as Field>::Scalar::from_bytes_mod_order_wide(&output))
|
||||
Some(hash_to_scalar(&[CONTEXT_STRING.as_bytes(), b"dkg", m]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use k256::{
|
|||
AffinePoint, ProjectivePoint, Scalar,
|
||||
};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use sha2::{digest::Update, Digest, Sha256};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use frost_core::{frost, Ciphersuite, Field, FieldError, Group, GroupError};
|
||||
|
||||
|
@ -142,6 +142,16 @@ impl Group for Secp256K1Group {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_to_array(inputs: &[&[u8]]) -> [u8; 32] {
|
||||
let mut h = Sha256::new();
|
||||
for i in inputs {
|
||||
h.update(i);
|
||||
}
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
}
|
||||
|
||||
/// hash2field implementation from <https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3>
|
||||
///
|
||||
/// From <https://github.com/serai-dex/serai/blob/5df74ac9e28f9299e674e98d08e64c99c34e579c/crypto/ciphersuite/src/kp256.rs#L45-L62>
|
||||
|
@ -212,28 +222,14 @@ impl Ciphersuite for Secp256K1Sha256 {
|
|||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.5-2.2.2.4
|
||||
fn H4(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha256::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("msg")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"msg", m])
|
||||
}
|
||||
|
||||
/// H5 for FROST(secp256k1, SHA-256)
|
||||
///
|
||||
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-6.5-2.2.2.5
|
||||
fn H5(m: &[u8]) -> Self::HashOutput {
|
||||
let h = Sha256::new()
|
||||
.chain(CONTEXT_STRING.as_bytes())
|
||||
.chain("com")
|
||||
.chain(m);
|
||||
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(h.finalize().as_slice());
|
||||
output
|
||||
hash_to_array(&[CONTEXT_STRING.as_bytes(), b"com", m])
|
||||
}
|
||||
|
||||
/// HDKG for FROST(secp256k1, SHA-256)
|
||||
|
|
Loading…
Reference in New Issue