Skip to content

Commit

Permalink
Implement secp256k1_XMD-SHA-256_SSWU_NU_ and secp256k1_XMD-SHA-256_SS…
Browse files Browse the repository at this point in the history
…WU_RO_
  • Loading branch information
azuchi committed Jan 12, 2023
1 parent a3cb937 commit fe70a7e
Show file tree
Hide file tree
Showing 12 changed files with 373 additions and 22 deletions.
3 changes: 3 additions & 0 deletions lib/ext/curve.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

require_relative "curve/secp256k1_3iso"
20 changes: 20 additions & 0 deletions lib/ext/curve/secp256k1_3iso.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true
module ECDSA
class Group
Secp256k1_3ISO =
new(
name: "secp256k1_3ISO",
p:
0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F,
a: 0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533,
b: 1771,
g: [
0xa677f67dec3b4e958267664f4bead0c300959b89cdfae2fbb7563af10a26088a,
0xb683b56744d1140cbda41b9853bb2fb7cc44b06dc61406db73c387aea4e680d3
],
n:
0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141,
h: 1
)
end
end
4 changes: 3 additions & 1 deletion lib/h2c.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# frozen_string_literal: true

require_relative "h2c/version"
require 'ecdsa'
require "ecdsa"
require_relative "ext/curve"

# Hash to Curves library.
# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html
Expand All @@ -12,6 +13,7 @@ class Error < StandardError
autoload :Expander, "h2c/expander"
autoload :Suite, "h2c/suite"
autoload :HashToPoint, "h2c/hash_to_point"
autoload :M2C, "h2c/m2c"

# Hash function name
module HashFunc
Expand Down
13 changes: 7 additions & 6 deletions lib/h2c/hash_to_point.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
module H2C
# Complete and secure function for hashing strings to points.
class HashToPoint

attr_reader :suite

# @param [H2C::Suite] suite Hash to curve suite
Expand All @@ -13,15 +12,17 @@ def initialize(suite)

# Hash returns a point on an elliptic curve given a message.
# @param [String] msg Message with binary to be hashed.
# @return [ECDSA::Point]
# @return [ECDSA::Point] point
def digest(msg)
if suite.ro
u = hash_to_field(msg, 2)
p0 = suite.map.map(u[0])
p1 = suite.map.map(u[1])
p0 + p1
else
u = hash_to_field(msg, 1)
suite.map.map(u[0])
end


end

# Hashes a msg of any length into an element of a finite field.
Expand All @@ -39,12 +40,12 @@ def hash_to_field(msg, count)
(0...suite.m).each do |j|
offset = suite.l * (j + i * suite.m)
t = pseudo[offset, (offset + suite.l)]
vj = t.unpack1('H*').to_i(16)
vj = t.unpack1("H*").to_i(16)
v[j] = field.mod(vj)
end
u[i] = v
end
u
u.flatten
end
end
end
11 changes: 11 additions & 0 deletions lib/h2c/m2c.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module H2C
# Map to Curve functions.
# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#section-6
module M2C
autoload :ISOGeny, "h2c/m2c/isogeny"
autoload :SSWU, "h2c/m2c/sswu"
autoload :SSWUAB0, "h2c/m2c/sswuab0"
end
end
9 changes: 9 additions & 0 deletions lib/h2c/m2c/isogeny.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
module H2C
module M2C
# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-isogeny-maps-for-suites
module ISOGeny
autoload :Secp256k1, "h2c/m2c/isogeny/secp256k1"
end
end
end
60 changes: 60 additions & 0 deletions lib/h2c/m2c/isogeny/secp256k1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true
module H2C
module M2C
module ISOGeny
# 3-isogeny map for secp256k1
# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#appendix-E.1
class Secp256k1
attr_reader :e0, :e1

X_NUM = [
0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7,
0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581,
0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262,
0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c
].freeze
X_DEN = [
0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b,
0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14,
1,
0
].freeze
Y_NUM = [
0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c,
0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3,
0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931,
0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84
].freeze
Y_DEN = [
0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b,
0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573,
0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f,
1
].freeze

def initialize
@e0 = ECDSA::Group::Secp256k1_3ISO
@e1 = ECDSA::Group::Secp256k1
end

def map(x, y)
f = e0.field

x_num = 0
x_den = 0
y_num = 0
y_den = 0
3.step(0, -1) do |i|
x_num = f.mod(x_num * x + X_NUM[i])
x_den = f.mod(x_den * x + X_DEN[i])
y_num = f.mod(y_num * x + Y_NUM[i])
y_den = f.mod(y_den * x + Y_DEN[i])
end
xx = f.mod(x_num * f.inverse(x_den))
yy = f.mod(y * (y_num * f.inverse(y_den)))
[xx, yy]
end
end
end
end
end
26 changes: 26 additions & 0 deletions lib/h2c/m2c/sswuab0.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true
module H2C
module M2C
# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#section-6.6.3
class SSWUAB0
attr_reader :sswu, :iso

# Constructor
# @param [H2C::M2C::ISOGeny] iso
# @param [Integer] z
def initialize(iso, z)
@sswu = SSWU.new(iso.e0, z)
@iso = iso
end

# https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#section-6.6.3
# @param [Integer] u
# @return [ECDSA::Point]
def map(u)
x, y = sswu.map(u)
coordinate = iso.map(x, y)
iso.e1.new_point(coordinate)
end
end
end
end
22 changes: 7 additions & 15 deletions lib/h2c/suite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,28 @@
module H2C
# Hash to curve suites
class Suite
attr_reader :id, :curve, :k, :exp, :m, :l, :ro, :map

attr_reader :id, :curve, :k, :exp, :m, :l, :ro

Secp256k1_XMDSHA256_SSWU_NU_ = "secp256k1_XMD:SHA-256_SSWU_NU_"
Secp256k1_XMDSHA256_SSWU_RO_ = "secp256k1_XMD:SHA-256_SSWU_RO_"
SECP256K1_XMDSHA256_SSWU_NU_ = "secp256k1_XMD:SHA-256_SSWU_NU_"
SECP256K1_XMDSHA256_SSWU_RO_ = "secp256k1_XMD:SHA-256_SSWU_RO_"

# Initialize suite
# @param [String] id Suite id.
# @param [String] dst Domain separation tag.
def initialize(id, dst)
@id = id
case id
when Secp256k1_XMDSHA256_SSWU_NU_
when SECP256K1_XMDSHA256_SSWU_NU_, SECP256K1_XMDSHA256_SSWU_RO_
@curve = ECDSA::Group::Secp256k1
@k = 128
@exp = Expander.get(HashFunc::SHA256, dst, @k)
@m = 1
@l = 48
@ro = false
when Secp256k1_XMDSHA256_SSWU_RO_
@curve = ECDSA::Group::Secp256k1
@k = 128
@exp = Expander.get(HashFunc::SHA256, dst, @k)
@m = 1
@l = 48
@ro = true
@map = M2C::SSWUAB0.new(H2C::M2C::ISOGeny::Secp256k1.new, -11)
@ro = (id == SECP256K1_XMDSHA256_SSWU_RO_)
else
raise H2C::Error, "suite #{suite} unsupported."
raise H2C::Error, "suite #{curve} unsupported."
end
end

end
end
90 changes: 90 additions & 0 deletions spec/fixtures/suites/secp256k1_XMD-SHA-256_SSWU_NU_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"L": "0x30",
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc24",
"ciphersuite": "secp256k1_XMD:SHA-256_SSWU_NU_",
"curve": "secp256k1",
"dst": "QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_NU_",
"expand": "XMD",
"field": {
"m": "0x1",
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
},
"hash": "sha256",
"k": "0x80",
"map": {
"name": "SSWU"
},
"randomOracle": false,
"vectors": [
{
"P": {
"x": "0xa4792346075feae77ac3b30026f99c1441b4ecf666ded19b7522cf65c4c55c5b",
"y": "0x62c59e2a6aeed1b23be5883e833912b08ba06be7f57c0e9cdc663f31639ff3a7"
},
"Q": {
"x": "0xa4792346075feae77ac3b30026f99c1441b4ecf666ded19b7522cf65c4c55c5b",
"y": "0x62c59e2a6aeed1b23be5883e833912b08ba06be7f57c0e9cdc663f31639ff3a7"
},
"msg": "",
"u": [
"0x0137fcd23bc3da962e8808f97474d097a6c8aa2881fceef4514173635872cf3b"
]
},
{
"P": {
"x": "0x3f3b5842033fff837d504bb4ce2a372bfeadbdbd84a1d2b678b6e1d7ee426b9d",
"y": "0x902910d1fef15d8ae2006fc84f2a5a7bda0e0407dc913062c3a493c4f5d876a5"
},
"Q": {
"x": "0x3f3b5842033fff837d504bb4ce2a372bfeadbdbd84a1d2b678b6e1d7ee426b9d",
"y": "0x902910d1fef15d8ae2006fc84f2a5a7bda0e0407dc913062c3a493c4f5d876a5"
},
"msg": "abc",
"u": [
"0xe03f894b4d7caf1a50d6aa45cac27412c8867a25489e32c5ddeb503229f63a2e"
]
},
{
"P": {
"x": "0x07644fa6281c694709f53bdd21bed94dab995671e4a8cd1904ec4aa50c59bfdf",
"y": "0xc79f8d1dad79b6540426922f7fbc9579c3018dafeffcd4552b1626b506c21e7b"
},
"Q": {
"x": "0x07644fa6281c694709f53bdd21bed94dab995671e4a8cd1904ec4aa50c59bfdf",
"y": "0xc79f8d1dad79b6540426922f7fbc9579c3018dafeffcd4552b1626b506c21e7b"
},
"msg": "abcdef0123456789",
"u": [
"0xe7a6525ae7069ff43498f7f508b41c57f80563c1fe4283510b322446f32af41b"
]
},
{
"P": {
"x": "0xb734f05e9b9709ab631d960fa26d669c4aeaea64ae62004b9d34f483aa9acc33",
"y": "0x03fc8a4a5a78632e2eb4d8460d69ff33c1d72574b79a35e402e801f2d0b1d6ee"
},
"Q": {
"x": "0xb734f05e9b9709ab631d960fa26d669c4aeaea64ae62004b9d34f483aa9acc33",
"y": "0x03fc8a4a5a78632e2eb4d8460d69ff33c1d72574b79a35e402e801f2d0b1d6ee"
},
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
"u": [
"0xd97cf3d176a2f26b9614a704d7d434739d194226a706c886c5c3c39806bc323c"
]
},
{
"P": {
"x": "0x17d22b867658977b5002dbe8d0ee70a8cfddec3eec50fb93f36136070fd9fa6c",
"y": "0xe9178ff02f4dab73480f8dd590328aea99856a7b6cc8e5a6cdf289ecc2a51718"
},
"Q": {
"x": "0x17d22b867658977b5002dbe8d0ee70a8cfddec3eec50fb93f36136070fd9fa6c",
"y": "0xe9178ff02f4dab73480f8dd590328aea99856a7b6cc8e5a6cdf289ecc2a51718"
},
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"u": [
"0xa9ffbeee1d6e41ac33c248fb3364612ff591b502386c1bf6ac4aaf1ea51f8c3b"
]
}
]
}
Loading

0 comments on commit fe70a7e

Please sign in to comment.