schnorr 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 552fd9baac0e3e4242003e0844c1e5d08dc69f46bf6b605f59293f9793c2c8a1
4
- data.tar.gz: 4de25e1831dc171450435256e4e15f5734bfa8da522c57b5ffb90c9d0f1c32f9
3
+ metadata.gz: d7824a03bb8227a4fda5c6abccc1a8081053c843e1b1a99d4f7a3b5b75e71dd2
4
+ data.tar.gz: 92f8bd807b630221607c0b9fc4661e1b0feada22271e13db4063ff60921d50ac
5
5
  SHA512:
6
- metadata.gz: dcff61f96ee167a43e31fa71b196c118ae8471c949271282c8d0f7b7bee3cc0ce94323d24e70c43619fdd3571f0084e652c1d251e0c07c59deccf63155757085
7
- data.tar.gz: 891acabe7a536901ae0209798df11a6f3031dc90e534446ac8982a225ce1ce21c1d011d4e4378942af7cd52c11962082690c4bd51830d604fb0ff31d1a057391
6
+ metadata.gz: 06f01d84487925f4ce93f03a9b183edadfaa7e191c1824c37bc1c1b3b63569eb77438ed6d2395856a42b27f20450116b5139f8bfe23f602c936611db4d668c14
7
+ data.tar.gz: 2f9a61849124e10bad500d54c91b56f40f77c9e93c12ad8b529473b2f0fb68838320b747eeffa9243369a88a3445160201e6be2f08e14dd2029e2df7a47f479c
@@ -1 +1 @@
1
- 2.6.2
1
+ 2.6.3
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.6.2
3
+ - 2.6.3
4
4
  - 2.5.5
5
- - 2.4.5
5
+ - 2.4.6
6
6
 
7
7
  bundler_args: --jobs=2
8
8
 
data/README.md CHANGED
@@ -131,15 +131,22 @@ session_id = session.id
131
131
  ## each participant create own session.
132
132
  session = Schnorr::MuSig.session_initialize(session_id, private_key, message, combined_pubkey, ell, index)
133
133
 
134
+ ## participant send his commitment of nonce before send nonce itself.
135
+ session.commitment
136
+
137
+ ## participant collect other participant's commitments.
138
+ session.commitments << commitment
139
+
134
140
  ## participant send his nonce and collect other participant's nonce.
135
141
  session.nonce
136
142
 
137
143
  other_nonces = [...]
138
144
 
139
145
  ## If collect all participant's nonce, then calculate combined nonce.
146
+ ## An error will occur if the previously collected commitment and nonce do not match.
140
147
  ## In this method, if jacobi(y(combined_point)) != 1,
141
148
  ## combined_point changed to combined_point.negate and session#nonce_negate changed to true.
142
- combined_nonce = session.nonce_combine(other_nonces)
149
+ combined_nonce = session.combine_nonce(other_nonces)
143
150
 
144
151
  ## each participants create partial signature
145
152
  partial_sig = session.partial_sign(message, combined_nonce, combined_pubkey)
@@ -46,8 +46,9 @@ module Schnorr
46
46
  # @param combined_pubkey (String) combined public key with binary format.
47
47
  # @param ell (String) ell with binary format.
48
48
  # @param index (Integer) public key index.
49
+ # @param num_signers (Integer) the number of signers.
49
50
  # @return (Schnorr::MuSig::Session) session object.
50
- def session_initialize(session_id, private_key, message, combined_pubkey, ell, index)
51
+ def session_initialize(session_id, private_key, message, combined_pubkey, ell, index, num_signers)
51
52
  raise ArgumentError, 'session_id must be 32 bytes.' if session_id && session_id.bytesize != 32
52
53
  raise ArgumentError, 'message must be 32 bytes.' unless message.bytesize == 32
53
54
  raise ArgumentError, 'combined_pubkey must be 33 bytes.' unless combined_pubkey.bytesize == 33
@@ -55,14 +56,13 @@ module Schnorr
55
56
  secret = ECDSA::Format::IntegerOctetString.encode(private_key, ECDSA::Group::Secp256k1.byte_length)
56
57
 
57
58
  field = ECDSA::PrimeField.new(ECDSA::Group::Secp256k1.order)
58
- session = Schnorr::MuSig::Session.new(session_id)
59
+ session = Schnorr::MuSig::Session.new(session_id, num_signers)
59
60
  coefficient = coefficient(ell, index)
60
61
  session.secret_key = field.mod(private_key * coefficient)
61
62
  session.secret_nonce = Digest::SHA256.digest(session.id + message + combined_pubkey + secret).unpack('H*').first.to_i(16)
62
63
  raise ArgumentError, 'secret nonce must be an integer in the ragen 1..n-1' unless field.include?(session.secret_nonce)
63
64
  point_r = ECDSA::Group::Secp256k1.new_point(session.secret_nonce)
64
65
  session.nonce = ECDSA::Format::PointOctetString.encode(point_r, compression: true)
65
- session.commitment = Digest::SHA256.digest(session.nonce)
66
66
  session
67
67
  end
68
68
 
@@ -3,25 +3,41 @@ module Schnorr
3
3
  class Session
4
4
 
5
5
  attr_reader :id # binary
6
+ attr_reader :num_signers # Integer
6
7
  attr_accessor :secret_key # Integer
7
8
  attr_accessor :secret_nonce # Integer
8
9
  attr_accessor :nonce # binary
9
- attr_accessor :commitment # binary
10
10
  attr_accessor :nonce_negate # Boolean
11
+ attr_reader :commitments # commitments for other participants Array[]
11
12
 
12
- def initialize(session_id = SecureRandom.random_bytes(32))
13
+ def initialize(session_id = SecureRandom.random_bytes(32), num_signers)
13
14
  @id = session_id
14
15
  @nonce_negate = false
16
+ @num_signers = num_signers
17
+ @commitments = []
15
18
  end
16
19
 
17
20
  def nonce_negate?
18
21
  @nonce_negate
19
22
  end
20
23
 
21
- # Combine nonce
24
+ # Get self nonce commitment
25
+ # @return (String) commitment with binary format.
26
+ def commitment
27
+ Digest::SHA256.digest(nonce)
28
+ end
29
+
30
+ # Get combine nonce
22
31
  # @param nonces (Array[String]) an array of other signer's nonce with binary format.
23
32
  # @return (String) combined nonce with binary format.
24
- def nonce_combine(nonces)
33
+ def combine_nonce(nonces)
34
+ raise ArgumentError, "Nonce is required for the number of other signers." unless num_signers == (nonces.length + 1)
35
+ raise ArgumentError, "The number of nonce and commitment does not match." unless nonces.length == commitments.length
36
+ # check nonce commitments
37
+ nonces.each do | nonce|
38
+ commitment = Digest::SHA256.digest(nonce)
39
+ raise ArgumentError, "Nonce: #{nonce.bth} is invalid. There is no corresponding commitment." unless commitments.include?(commitment)
40
+ end
25
41
  points = ([nonce]+ nonces).map.with_index {|n, index|ECDSA::Format::PointOctetString.decode(n, ECDSA::Group::Secp256k1)}
26
42
  r_point = points.inject(:+)
27
43
  unless ECDSA::PrimeField.jacobi(r_point.y, ECDSA::Group::Secp256k1.field.prime) == 1
@@ -1,3 +1,3 @@
1
1
  module Schnorr
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schnorr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-09 00:00:00.000000000 Z
11
+ date: 2019-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ecdsa