Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ where
_marker: core::marker::PhantomData<G>,
}

const WORD_SIZE: usize = 32;

fn length_to_bytes(x: usize) -> [u8; WORD_SIZE] {
let mut bytes = [0u8; WORD_SIZE];
let x_bytes = x.to_be_bytes();
bytes[WORD_SIZE - x_bytes.len()..].copy_from_slice(&x_bytes);
bytes
}

impl<G, H> Codec for ByteSchnorrCodec<G, H>
where
G: Group + GroupEncoding,
Expand All @@ -63,10 +72,11 @@ where
fn new(protocol_id: &[u8], session_id: &[u8], instance_label: &[u8]) -> Self {
let iv = {
let mut tmp = H::new([0u8; 32]);
tmp.absorb(&length_to_bytes(protocol_id.len()));
tmp.absorb(protocol_id);
tmp.ratchet();
tmp.absorb(&length_to_bytes(session_id.len()));
tmp.absorb(session_id);
tmp.ratchet();
tmp.absorb(&length_to_bytes(instance_label.len()));
tmp.absorb(instance_label);
tmp.squeeze(32).try_into().unwrap()
};
Expand Down
1 change: 1 addition & 0 deletions src/tests/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mod rng;

mod test_duplex_sponge;
mod test_vectors;
mod test_vectors_with_fixed_label;
2 changes: 1 addition & 1 deletion src/tests/spec/test_duplex_sponge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn hex_decode(hex_str: &str) -> Vec<u8> {
}

fn load_test_vectors() -> HashMap<String, TestVector> {
let json_data = include_str!("./duplexSpongeVectors.json");
let json_data = include_str!("./vectors/duplexSpongeVectors.json");
serde_json::from_str(json_data).expect("Failed to parse test vectors JSON")
}

Expand Down
2 changes: 1 addition & 1 deletion src/tests/spec/test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ generate_ni_function!(
fn test_spec_testvectors() {
let seed = b"hello world";
let iv = *b"yellow submarineyellow submarine";
let vectors = extract_vectors("src/tests/spec/allVectors.json").unwrap();
let vectors = extract_vectors("src/tests/spec/vectors/allVectors.json").unwrap();

let functions: [fn(&[u8], [u8; 32]) -> (Vec<Scalar>, Vec<u8>); 5] = [
NI_discrete_logarithm,
Expand Down
125 changes: 125 additions & 0 deletions src/tests/spec/test_vectors_with_fixed_label.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use bls12_381::{G1Projective as G, Scalar};
use core::str;
use hex::FromHex;
use json::JsonValue;
use std::fs;

use crate::codec::KeccakByteSchnorrCodec;
use crate::fiat_shamir::NISigmaProtocol;
use crate::tests::spec::{
custom_schnorr_protocol::SchnorrProtocolCustom, random::SRandom, rng::TestDRNG,
};
use crate::tests::test_utils::{
bbs_blind_commitment_computation, discrete_logarithm, dleq, pedersen_commitment,
pedersen_commitment_dleq,
};

type NIProtocol = NISigmaProtocol<SchnorrProtocolCustom<G>, KeccakByteSchnorrCodec<G>>;

/// Macro to generate non-interactive sigma protocols test functions
macro_rules! generate_ni_function {
($name:ident, $test_fn:ident, $($param:tt),*) => {
#[allow(non_snake_case)]
fn $name(seed: &[u8], session_id: &[u8]) -> (Vec<Scalar>, Vec<u8>, Vec<u8>) {
let mut rng = TestDRNG::new(seed);
let (instance, witness) = $test_fn($(generate_ni_function!(@arg rng, $param)),*);

let statement = instance.label();
let protocol = SchnorrProtocolCustom(instance);
let nizk = NIProtocol::new(session_id, protocol);

let proof_bytes = nizk.prove_batchable(&witness, &mut rng).unwrap();
let verified = nizk.verify_batchable(&proof_bytes).is_ok();
assert!(verified, "Fiat-Shamir Schnorr proof verification failed");
(witness, proof_bytes, statement)
}
};

(@arg $rng:ident, $type:ident) => {
G::$type(&mut $rng)
};
(@arg $rng:ident, [$type:ident; $count:expr]) => {
(0..$count).map(|_| G::$type(&mut $rng)).collect::<Vec<_>>().try_into().unwrap()
};
}

generate_ni_function!(NI_discrete_logarithm, discrete_logarithm, srandom);
generate_ni_function!(NI_dleq, dleq, prandom, srandom);
generate_ni_function!(
NI_pedersen_commitment,
pedersen_commitment,
prandom,
srandom,
srandom
);
generate_ni_function!(
NI_pedersen_commitment_dleq,
pedersen_commitment_dleq,
[prandom; 4],
[srandom; 2]
);
generate_ni_function!(
NI_bbs_blind_commitment_computation,
bbs_blind_commitment_computation,
[prandom; 4],
[srandom; 3],
srandom
);

#[allow(clippy::type_complexity)]
#[allow(non_snake_case)]
#[test]
fn test_spec_testvectors() {
let seed = b"hello world";
let session_id = b"yellow submarineyellow submarine";
let vectors = extract_vectors("src/tests/spec/vectors/fixedLabelVectors.json").unwrap();

let functions: [fn(&[u8], &[u8]) -> (Vec<Scalar>, Vec<u8>, Vec<u8>); 5] = [
NI_discrete_logarithm,
NI_dleq,
NI_pedersen_commitment,
NI_pedersen_commitment_dleq,
NI_bbs_blind_commitment_computation,
];

for (i, f) in functions.iter().enumerate() {
let (_, proof_bytes, statement) = f(seed, session_id);
assert_eq!(
session_id.as_slice(),
vectors[i].0.as_slice(),
"context for test vector {i} does not match"
);
assert_eq!(
proof_bytes, vectors[i].1,
"proof bytes for test vector {i} does not match"
);
assert_eq!(
statement, vectors[i].2,
"statement for test vector {i} does not match"
);
}
}

#[allow(clippy::type_complexity)]
fn extract_vectors(path: &str) -> json::Result<Vec<(Vec<u8>, Vec<u8>, Vec<u8>)>> {
let content = fs::read_to_string(path).expect("Unable to read JSON file");
let root: JsonValue = json::parse(&content).expect("JSON parsing error");
root.entries()
.map(|(_, obj)| {
let context_hex = obj["Context"]
.as_str()
.expect("Context field not found or not a string");
let proof_hex = obj["Proof"]
.as_str()
.expect("Proof field not found or not a string");
let statement_hex = obj["Statement"]
.as_str()
.expect("Statement field not found or not a string");
Ok((
Vec::from_hex(context_hex).unwrap(),
Vec::from_hex(proof_hex).unwrap(),
Vec::from_hex(statement_hex).unwrap(),
))
})
.collect()
}
File renamed without changes.
32 changes: 32 additions & 0 deletions src/tests/spec/vectors/fixedLabelVectors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"discrete_logarithm_with_session_ID": {
"Ciphersuite": "sigma/OWKeccak1600+Bls12381",
"Context": "79656c6c6f77207375626d6172696e6579656c6c6f77207375626d6172696e65",
"Proof": "80c96c2822d816de609d4b72dd0b2a9409a3402338c977467225e7f506a60f3153a7f447450d7336c0ef15e4151349d95936c8894ec7803ab9e2642bea06ff1cd8e1311a853260eb081610d57d7dccf7",
"Statement": "010000000100000001000000000000000000000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb8e6e5ac1f85d0bfd5123a9f7eef4030590497392023dde2cd1df43995f90839a480cd6dc33f857469586855d7face415"
},
"dleq_with_session_ID": {
"Ciphersuite": "sigma/OWKeccak1600+Bls12381",
"Context": "79656c6c6f77207375626d6172696e6579656c6c6f77207375626d6172696e65",
"Proof": "a01abd54895b7df2d476b2371e1796278a114f7dd1514e05cc1c0c07d40957268684c8887aa3f8cee33856ca325412f5859a8bb9d31747dafffcfe70acd32bcb30b45db8333cd157f561039e654e2f8314ee648604afdb4c2a4c30ae964911926139d5d2b2e515d7a71d0907e472a6f7e647a6474ca22e5eb14895324a98b967",
"Statement": "02000000010000000100000000000000000000000300000001000000000000000200000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb80c96c2822d816de609d4b72dd0b2a9409a3402338c977467225e7f506a60f3153a7f447450d7336c0ef15e4151349d98e6e5ac1f85d0bfd5123a9f7eef4030590497392023dde2cd1df43995f90839a480cd6dc33f857469586855d7face4158f145e1c22e60229fbfa9a754244a51935ec5422d4aabbb83427cb213ff81a48a49471f74c371564afd334522d56f4b4"
},
"pedersen_commitment_with_session_ID": {
"Ciphersuite": "sigma/OWKeccak1600+Bls12381",
"Context": "79656c6c6f77207375626d6172696e6579656c6c6f77207375626d6172696e65",
"Proof": "91c620e60e68502ab1e0f0fa6b9f7e3225f678596da80c0e950e4149078562518ad37ed6177c71ebd6e2ca5fc32457d87182c691d77c2352c6b7742c2e538711742158c8851c7e00873b45f1ae5a49060524ec782635e94be60f3100297a2cb946f51cfbc9980f5f661c8be4190b2cee",
"Statement": "0100000002000000020000000000000000000000010000000100000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb8e6e5ac1f85d0bfd5123a9f7eef4030590497392023dde2cd1df43995f90839a480cd6dc33f857469586855d7face415b4054b3c7e864c3dc66fb10b967d874a871451d2b949e27c02f6ee74f96d68daadea1a917dba760114bb67100f74060d"
},
"pedersen_commitment_dleq_with_session_ID": {
"Ciphersuite": "sigma/OWKeccak1600+Bls12381",
"Context": "79656c6c6f77207375626d6172696e6579656c6c6f77207375626d6172696e65",
"Proof": "b3e0e2f9f68405774ae13cc7271ffa66199c079a332977a0170ff134739feccc674ce0be72e236312ecf3194cfca25eb8253ccdd07c6b67dd79f3a27f214bfcb42d2b0f34432ec795ab286f099bb19ed011b0b10828e58a10d5ef8fb4f615bf84c2c0331fd2de990e9958b4899582a8ceab68529e7771a0a275ab4374ee18cbe1c212b766f327efe9e5be3462ae767583208938915738036650542c6c1916571",
"Statement": "020000000200000002000000000000000000000001000000010000000500000002000000000000000300000001000000040000008e6e5ac1f85d0bfd5123a9f7eef4030590497392023dde2cd1df43995f90839a480cd6dc33f857469586855d7face41580c96c2822d816de609d4b72dd0b2a9409a3402338c977467225e7f506a60f3153a7f447450d7336c0ef15e4151349d992a2d40d620847feca5cb85e5276e72d051568faaf0eab836ba92407dd7a0b7c7cac7b11770403fa368c76b3d01fee23a01abd54895b7df2d476b2371e1796278a114f7dd1514e05cc1c0c07d40957268684c8887aa3f8cee33856ca325412f581a513b89ce4a0e3213ba6dbb8af71898c6c6b4ad96a6d83de7c280fa91065f705b029f0c4db29521190cd576ff5d49a954d82081d55a0f02505bd29a97e5fcd079f2f5dc6901fdf9df178fc0ae4f47b8c2d13bfb6ac3adc06c5d7c69dd3c7f4"
},
"bbs_blind_commitment_computation_with_session_ID": {
"Ciphersuite": "sigma/OWKeccak1600+Bls12381",
"Context": "79656c6c6f77207375626d6172696e6579656c6c6f77207375626d6172696e65",
"Proof": "803d5d4fdb311967832758ae7402d03304b570f97c0756e5385a50622d0ac7b5de87fe14d15041b1564ba4893a1187306c55832724d087dfccf36f4541b4e4449cd7acbadceb4844ade304aca0007fb92be0e35119da7e7b597b96f888517ada2425b33068baa921bc671652367a8e3e5b18c4072e20c532197f804b35499402fd78fd04e82be56ac235349b0ae61b2f0afd8494ffe5f987824e3029798eee96e15d2e7e870f250878ac5110f27e41d9",
"Statement": "01000000040000000400000000000000000000000100000001000000020000000200000003000000030000008e6e5ac1f85d0bfd5123a9f7eef4030590497392023dde2cd1df43995f90839a480cd6dc33f857469586855d7face41580c96c2822d816de609d4b72dd0b2a9409a3402338c977467225e7f506a60f3153a7f447450d7336c0ef15e4151349d9a01abd54895b7df2d476b2371e1796278a114f7dd1514e05cc1c0c07d40957268684c8887aa3f8cee33856ca325412f581a513b89ce4a0e3213ba6dbb8af71898c6c6b4ad96a6d83de7c280fa91065f705b029f0c4db29521190cd576ff5d49a831cb36c8ff357b10806173cf5ad3d7e9a404fe66d2675138086a43b2c8627526e155e6195f55164187c8f4a101a6208"
}
}
Loading