schnorr 0.1.0 → 0.2.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: 7cd8574f53f2db668bf4faf56f69cd2339b6366dd2063ceb1774ea62e4da534c
4
- data.tar.gz: 556a46fe20dfc6e733f5eb1a9809b32a097afcaca97834074edccee408ee992c
3
+ metadata.gz: 27c028f23478e028b813e4bf12bbb1bd6b9f92b75d758554c71e298b0f3a9077
4
+ data.tar.gz: 2943cdc9afc73fecc8804b6c498ef0f55a850a63b71422ecf716c0d3b496e164
5
5
  SHA512:
6
- metadata.gz: 8e97068a47a5c3bf6fc1d1e2aa650a073bfbe0ea7cd67b00b30e8051bf6a1773e7d418ee07840c366df84050367fe2ec832d3ef00c655076ec50911eb106255b
7
- data.tar.gz: '0182ad307f20f2c3752cd23d9b1e9e3c78681601a493f895ea9e07e69102c3d6a9820c50678d11ee0d16ec584e9e2e57bc09f949c712ebe2cf9af6c9a33d92bc'
6
+ metadata.gz: 94e5c230cbda7f0fa66a30da0f3a62d2950aaf42b34e2c0d24980f65616d0c31b5b289eac48eaf717fd3052d3ea57d8664d373bec16298c36611c38d51162804
7
+ data.tar.gz: f83ad1edee227ee190495ae58743dc461ca1e0753925ad3c01fe6d68ab92bf02b8e4d00c3043fdb1eb2f2bd568791e0f80b3615d478c6c99f66565a72090eddf
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Schnorrrb [![Build Status](https://travis-ci.org/chaintope/schnorrrb.svg?branch=master)](https://travis-ci.org/chaintope/schnorrrb) [![Gem Version](https://badge.fury.io/rb/schnorrrb.svg)](https://badge.fury.io/rb/schnorrrb) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
1
+ # Schnorrrb [![Build Status](https://travis-ci.org/chaintope/schnorrrb.svg?branch=master)](https://travis-ci.org/chaintope/schnorrrb) [![Gem Version](https://badge.fury.io/rb/schnorr.svg)](https://badge.fury.io/rb/schnorr) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
2
2
 
3
3
  This is a Ruby implementation of the Schnorr signature scheme over the elliptic curve.
4
4
  This implementation relies on the [ecdsa gem](https://github.com/DavidEGrayson/ruby_ecdsa) for operate elliptic curves.
@@ -65,6 +65,27 @@ result = Schnorr.valid_sig?(message, public_key, signature)
65
65
  sig = Schnorr::Signature.decode(signature)
66
66
  ```
67
67
 
68
+ ### Batch verification
69
+
70
+ ```ruby
71
+ require 'schnorr'
72
+
73
+ pubkeys = ['03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B'].pack('H*')
74
+ pubkeys << ['02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659'].pack('H*')
75
+ ...
76
+
77
+ messages = ['5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C'].pack('H*')
78
+ messages << ['243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89'].pack('H*')
79
+ ...
80
+
81
+ signatures = [`00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380`].pack('H*')
82
+ signatures << [`787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C`].pack('H*')
83
+ ...
84
+
85
+ # batch verify signature.(result is true or false)
86
+ result = Schnorr.valid_sig?(messages, pubkeys, signatures)
87
+ ```
88
+
68
89
  ### Change elliptic curve
69
90
 
70
91
  This library use `secp256k1` curve as default. If you use another curve, you need to specify curve as following:
@@ -1,3 +1,3 @@
1
1
  module Schnorr
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/schnorr.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ecdsa'
2
+ require 'securerandom'
2
3
  require_relative 'schnorr/signature'
3
4
 
4
5
  module Schnorr
@@ -39,6 +40,48 @@ module Schnorr
39
40
  false
40
41
  end
41
42
 
43
+ # Batch verification
44
+ # @param messages (Array[String]) The array of message with binary format.
45
+ # @param public_keys (Array[String]) The array of public key with binary format.
46
+ # @param signatures (Array[String]) The array of signatures with binary format.
47
+ # @param group (ECDSA::Group) The curve that is being used.
48
+ # @return (Boolean) whether signature is valid.
49
+ def valid_sigs?(messages, public_keys, signatures, group: ECDSA::Group::Secp256k1)
50
+ raise ArgumentError, 'all parameters must be an array with the same length.' if messages.size != public_keys.size || public_keys.size != signatures.size
51
+ field = group.field
52
+ pubkeys = public_keys.map{|p| ECDSA::Format::PointOctetString.decode(p, group)}
53
+ sigs = signatures.map do|signature|
54
+ sig = Schnorr::Signature.decode(signature)
55
+ raise Schnorr::InvalidSignatureError, 'Invalid signature: r is not in the field.' unless field.include?(sig.r)
56
+ raise Schnorr::InvalidSignatureError, 'Invalid signature: s is not in the field.' unless field.include?(sig.s)
57
+ raise Schnorr::InvalidSignatureError, 'Invalid signature: r is zero.' if sig.r.zero?
58
+ raise Schnorr::InvalidSignatureError, 'Invalid signature: s is zero.' if sig.s.zero?
59
+ sig
60
+ end
61
+ left = 0
62
+ right = nil
63
+ pubkeys.each_with_index do |pubkey, i|
64
+ r = sigs[i].r
65
+ s = sigs[i].s
66
+ e = create_challenge(r, pubkey, messages[i], field, group)
67
+ c = field.mod(r.pow(3) + 7)
68
+ y = c.pow((field.prime + 1)/4, field.prime)
69
+ raise Schnorr::InvalidSignatureError, 'c is not equal to y^2.' unless c == y.pow(2, field.prime)
70
+ r_point = ECDSA::Point.new(group, r, y)
71
+ if i == 0
72
+ left = s
73
+ right = r_point + pubkey.multiply_by_scalar(e)
74
+ else
75
+ a = 1 + SecureRandom.random_number(group.order - 1)
76
+ left += (a * s)
77
+ right += (r_point.multiply_by_scalar(a) + pubkey.multiply_by_scalar(a * e))
78
+ end
79
+ end
80
+ group.new_point(left) == right
81
+ rescue InvalidSignatureError, ECDSA::Format::DecodeError
82
+ false
83
+ end
84
+
42
85
  # Verifies the given {Signature} and raises an {InvalidSignatureError} if it is invalid.
43
86
  # @param message (String) A message to be signed with binary format.
44
87
  # @param public_key (String) The public key with binary format.
@@ -59,7 +102,6 @@ module Schnorr
59
102
 
60
103
  r = group.new_point(sig.s) + pubkey.multiply_by_scalar(e).negate
61
104
 
62
-
63
105
  if r.infinity? || ECDSA::PrimeField.jacobi(r.y, group.field.prime) != 1 || r.x != sig.r
64
106
  raise Schnorr::InvalidSignatureError, 'signature verification failed.'
65
107
  end
data/schnorrrb.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "schnorr"
8
8
  spec.version = Schnorr::VERSION
9
9
  spec.authors = ["azuchi"]
10
- spec.email = ["azuchi@haw.co.jp"]
10
+ spec.email = ["azuchi@chaintope.com"]
11
11
 
12
12
  spec.summary = %q{The ruby implementation of Schnorr signature.}
13
13
  spec.description = %q{The ruby implementation of Schnorr signature.}
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.1.0
4
+ version: 0.2.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-03-27 00:00:00.000000000 Z
11
+ date: 2019-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ecdsa
@@ -68,7 +68,7 @@ dependencies:
68
68
  version: '3.0'
69
69
  description: The ruby implementation of Schnorr signature.
70
70
  email:
71
- - azuchi@haw.co.jp
71
+ - azuchi@chaintope.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
@@ -108,7 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  requirements: []
111
- rubygems_version: 3.0.3
111
+ rubyforge_project:
112
+ rubygems_version: 2.7.8
112
113
  signing_key:
113
114
  specification_version: 4
114
115
  summary: The ruby implementation of Schnorr signature.