From 787f75ab390cc5d5c8e26ce4fc1da912d5d1bfa8 Mon Sep 17 00:00:00 2001 From: azuchi Date: Tue, 6 Feb 2024 18:01:32 +0900 Subject: [PATCH] Add modulo argument to HashToPoint#hash_to_field for FROST --- lib/h2c/hash_to_point.rb | 11 ++++++----- spec/h2c/hash_to_point_spec.rb | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/h2c/hash_to_point.rb b/lib/h2c/hash_to_point.rb index 6b921da..b1a563d 100644 --- a/lib/h2c/hash_to_point.rb +++ b/lib/h2c/hash_to_point.rb @@ -31,19 +31,20 @@ def digest(msg) # https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-hash_to_field-implementatio # @param [String] msg A byte string containing the message to hash. # @param [Integer] count The number of elements of Field to output. + # @param [Integer] modulo (Optional) This value is a finite field of characteristic p in the hash to curve specification. + # Other protocols such as FROST can be order of curve. # @return [Array] - def hash_to_field(msg, count) - field = suite.curve.field + def hash_to_field(msg, count, modulo = suite.curve.field.prime) len = count * suite.m * suite.l pseudo = suite.exp.expand(msg, len) u = [] - (0...count).each do |i| + count.times do |i| v = [] - (0...suite.m).each do |j| + suite.m.times do |j| offset = suite.l * (j + i * suite.m) t = pseudo[offset, (offset + suite.l)] vj = t.unpack1("H*").to_i(16) - v[j] = field.mod(vj) + v[j] = vj % modulo end u[i] = v end diff --git a/spec/h2c/hash_to_point_spec.rb b/spec/h2c/hash_to_point_spec.rb index 148ea9d..cca7017 100644 --- a/spec/h2c/hash_to_point_spec.rb +++ b/spec/h2c/hash_to_point_spec.rb @@ -22,4 +22,20 @@ end end end + + describe "hash to field" do + context "with modulo" do + it do + dst = "FROST-secp256k1-SHA256-v1" + "nonce" + h2c = H2C.get(H2C::Suite::SECP256K1_XMDSHA256_SSWU_NU_, dst) + msg = [ + "7ea5ed09af19f6ff21040c07ec2d2adbd35b759da5a401d4c99dd26b82391cb208f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1ea2b01f4254c" + ].pack("H*") + field = h2c.hash_to_field(msg, 1, ECDSA::Group::Secp256k1.order).first + expect(field).to eq( + 0x841d3a6450d7580b4da83c8e618414d0f024391f2aeb511d7579224420aa81f0 + ) + end + end + end end