From f4392e3c9acebc1faf2ea672a39a9cfbe380fdc4 Mon Sep 17 00:00:00 2001 From: Christian Paquin Date: Thu, 6 Jul 2023 18:48:42 -0400 Subject: [PATCH] Implemented PR 267 and 268, with test vectors from PR 273 --- fetch-test-vectors.sh | 4 +++- src/bbs.ts | 42 +++++++++++++----------------------------- src/ciphersuite.ts | 11 +++++------ 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/fetch-test-vectors.sh b/fetch-test-vectors.sh index 8d74346..693a1b9 100755 --- a/fetch-test-vectors.sh +++ b/fetch-test-vectors.sh @@ -8,7 +8,9 @@ fi mkdir -p fixtures -urlPrefix="https://raw.githubusercontent.com/decentralized-identity/bbs-signature/main/tooling/fixtures/fixture_data/" +urlPrefix="https://raw.githubusercontent.com/decentralized-identity/bbs-signature/vasilis/draft03-fixtures/tooling/fixtures/fixture_data/" +# TODO: revert back after spec PR 273 is merged +#urlPrefix="https://raw.githubusercontent.com/decentralized-identity/bbs-signature/main/tooling/fixtures/fixture_data/" fetch_file() { local suite=$1 diff --git a/src/bbs.ts b/src/bbs.ts index 27be508..b4baf0a 100644 --- a/src/bbs.ts +++ b/src/bbs.ts @@ -257,20 +257,13 @@ export class BBS { async create_generators(length: number): Promise { const count = length + 1; // Q1, and generators const seed_dst = Buffer.from(this.cs.ciphersuite_id + 'SIG_GENERATOR_SEED_', 'utf-8'); - let v = this.cs.expand_message(this.cs.generator_seed, seed_dst, this.cs.seed_len); - let n = 1; + let v = this.cs.expand_message(this.cs.generator_seed, seed_dst, this.cs.expand_len); const generators: G1Point[] = []; - for (let i = 0; i < count; i++) { - let cont = true; - let candidate = G1Point.Identity; - while (cont) { - v = this.cs.expand_message(utils.concat(v, utils.i2osp(n, 4)), seed_dst, this.cs.seed_len); - n += 1; - candidate = await this.cs.hash_to_curve_g1(v); // generator_dst specified in the hash_to_curve_g1 function directly - cont = generators.includes(candidate); - } - generators.push(candidate); - utils.log("candidate " + i + ": ", utils.bytesToHex(candidate.toOctets())); + for (let i = 1; i <= count; i++) { + v = this.cs.expand_message(utils.concat(v, utils.i2osp(i, 8)), seed_dst, this.cs.expand_len); + const generator = await this.cs.hash_to_curve_g1(v, this.cs.ciphersuite_id + 'SIG_GENERATOR_DST_'); + generators.push(generator); + utils.log("generator " + i + ": ", utils.bytesToHex(generator.toOctets())); } return { Q1: generators[0], @@ -288,17 +281,8 @@ export class BBS { // https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html#name-hash-to-scalar hash_to_scalar(msg_octets: Uint8Array, dst: Uint8Array = Buffer.from(this.cs.ciphersuite_id + "H2S_", "utf8")): FrScalar { - let hashed_scalar: FrScalar = FrScalar.Zero; - let counter = 0; - while (hashed_scalar.equals(FrScalar.Zero)) { - if (counter > 255) { - throw "hash_to_scalar failed, counter > 255"; - } - const msg_prime = utils.concat(msg_octets, utils.i2osp(counter, 1)); - const uniform_bytes = this.cs.expand_message(msg_prime, dst, this.cs.expand_len); - hashed_scalar = utils.os2ip(uniform_bytes); - counter++; - } + const uniform_bytes = this.cs.expand_message(msg_octets, dst, this.cs.expand_len); + const hashed_scalar = utils.os2ip(uniform_bytes); return hashed_scalar; } @@ -315,11 +299,11 @@ export class BBS { // https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html#name-challenge-calculation calculate_challenge(ABar: G1Point, BBar: G1Point, C: G1Point, i_array: number[], msg_array: FrScalar[], domain: FrScalar, ph: Uint8Array): FrScalar { - const c_input = utils.concat( - this.serialize([ABar, BBar, C, i_array.length, ...i_array, ...msg_array, domain]), - utils.i2osp(ph.length, 8), - ph); - const challenge = this.hash_to_scalar(c_input); + const challenge = this.hash_to_scalar( + utils.concat( + this.serialize([ABar, BBar, C, i_array.length, ...i_array, ...msg_array, domain]), + utils.i2osp(ph.length, 8), + ph)); return challenge; } diff --git a/src/ciphersuite.ts b/src/ciphersuite.ts index 8136aba..fca0009 100644 --- a/src/ciphersuite.ts +++ b/src/ciphersuite.ts @@ -11,15 +11,14 @@ export class Ciphersuite { hash_to_curve_suite: string; P1: G1Point; generator_seed: Uint8Array; - hash_to_curve_g1 = async (input: Uint8Array) => { - return G1Point.hashToCurve(input, this.ciphersuite_id + "SIG_GENERATOR_DST_"); + hash_to_curve_g1 = async (input: Uint8Array, dst: string) => { + return G1Point.hashToCurve(input, dst); } - seed_len = 48; // ceil((ceil(log2(r)) + k)/8) expand_len = 48; // ceil((ceil(log2(r)) + k)/8) expand_message: (message: Uint8Array, dst: Uint8Array, len: number) => Uint8Array; constructor(cipherSuiteBaseId: string, P1: G1Point, expand_message: (message: Uint8Array, dst: Uint8Array, len: number) => Uint8Array) { - this.ciphersuite_id = cipherSuiteBaseId + "H2G_"; + this.ciphersuite_id = cipherSuiteBaseId + "H2G_HM2S_"; this.hash_to_curve_suite = cipherSuiteBaseId; this.P1 = P1; this.generator_seed = Buffer.from(this.ciphersuite_id + "MESSAGE_GENERATOR_SEED", 'utf-8'); @@ -29,12 +28,12 @@ export class Ciphersuite { export const BLS12_381_SHA256_Ciphersuite = new Ciphersuite( "BBS_BLS12381G1_XMD:SHA-256_SSWU_RO_", - G1Point.fromOctets(hexToBytes("864df3ae75a023852b577c6aa46d1608d7bfb73c59c73dfd47250ea01c04ec1ad20560e8e4aca82296ca7c4e1b7c3620")), + G1Point.fromOctets(hexToBytes("a8ce256102840821a3e94ea9025e4662b205762f9776b3a766c872b948f1fd225e7c59698588e70d11406d161b4e28c9")), expand_message_xmd ); export const BLS12_381_SHAKE_256_Ciphersuite = new Ciphersuite( "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_", - G1Point.fromOctets(hexToBytes("8fbd0548aada70863646feef018a867981b85ab22efb80a314dc96a4efaeaeef2e40f0d40524a0dcf5ae8fe5777d6d93")), + G1Point.fromOctets(hexToBytes("8929dfbc7e6642c4ed9cba0856e493f8b9d7d5fcb0c31ef8fdcd34d50648a56c795e106e9eada6e0bda386b414150755")), expand_message_xof );