schnorr 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.