nis-ruby 0.0.12 → 0.0.13
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 +4 -4
- data/.travis.yml +1 -0
- data/README.md +12 -9
- data/examples/transactions/importance_transfer.rb +1 -4
- data/examples/transactions/mosaic_definition_creation.rb +1 -4
- data/examples/transactions/mosaic_supply_change.rb +1 -4
- data/examples/transactions/multisig.rb +1 -6
- data/examples/transactions/multisig_add_cosignatory.rb +1 -4
- data/examples/transactions/multisig_aggregate_modification.rb +1 -4
- data/examples/transactions/multisig_signature.rb +2 -5
- data/examples/transactions/provision_namespace.rb +1 -4
- data/examples/transactions/transfer.rb +1 -4
- data/examples/transactions/transfer_remote.rb +19 -0
- data/lib/nis/endpoint/account/generate.rb +1 -1
- data/lib/nis/endpoint/account/get.rb +4 -4
- data/lib/nis/endpoint/account/harvests.rb +1 -1
- data/lib/nis/endpoint/account/historical.rb +1 -1
- data/lib/nis/endpoint/account/importances.rb +1 -1
- data/lib/nis/endpoint/account/lock.rb +1 -1
- data/lib/nis/endpoint/account/mosaic.rb +2 -2
- data/lib/nis/endpoint/account/namespace.rb +1 -1
- data/lib/nis/endpoint/account/status.rb +1 -1
- data/lib/nis/endpoint/account/transfers.rb +3 -3
- data/lib/nis/endpoint/account/unconfirmed_transactions.rb +1 -1
- data/lib/nis/endpoint/account/unlock.rb +1 -1
- data/lib/nis/endpoint/account/unlocked.rb +1 -1
- data/lib/nis/endpoint/block/at.rb +1 -1
- data/lib/nis/endpoint/block/get.rb +1 -1
- data/lib/nis/endpoint/chain/height.rb +1 -1
- data/lib/nis/endpoint/chain/last_block.rb +1 -1
- data/lib/nis/endpoint/chain/score.rb +1 -1
- data/lib/nis/endpoint/debug/connections.rb +3 -3
- data/lib/nis/endpoint/debug/time_synchronization.rb +1 -1
- data/lib/nis/endpoint/heartbeat.rb +1 -1
- data/lib/nis/endpoint/local/account/transfers.rb +3 -3
- data/lib/nis/endpoint/local/chain.rb +1 -1
- data/lib/nis/endpoint/namespace.rb +1 -1
- data/lib/nis/endpoint/namespace/mosaic.rb +1 -1
- data/lib/nis/endpoint/namespace/root.rb +1 -1
- data/lib/nis/endpoint/node/active_peers.rb +1 -1
- data/lib/nis/endpoint/node/boot.rb +1 -1
- data/lib/nis/endpoint/node/experiences.rb +1 -1
- data/lib/nis/endpoint/node/extended_info.rb +1 -1
- data/lib/nis/endpoint/node/info.rb +1 -1
- data/lib/nis/endpoint/node/peer_list.rb +3 -3
- data/lib/nis/endpoint/status.rb +1 -1
- data/lib/nis/endpoint/transaction/announce.rb +4 -4
- data/lib/nis/endpoint/transaction/prepareAnnounce.rb +4 -4
- data/lib/nis/keypair.rb +13 -3
- data/lib/nis/request/announce.rb +47 -2
- data/lib/nis/request/prepare_announce.rb +1 -1
- data/lib/nis/struct/account_importance_view_model.rb +1 -1
- data/lib/nis/struct/account_info.rb +1 -1
- data/lib/nis/struct/account_meta_data.rb +1 -1
- data/lib/nis/struct/account_meta_data_pair.rb +1 -1
- data/lib/nis/struct/account_private_key_transactions_page.rb +1 -1
- data/lib/nis/struct/application_meta_data.rb +1 -1
- data/lib/nis/struct/audit_collection.rb +1 -1
- data/lib/nis/struct/audit_info.rb +1 -1
- data/lib/nis/struct/block.rb +1 -1
- data/lib/nis/struct/block_height.rb +1 -1
- data/lib/nis/struct/block_score.rb +1 -1
- data/lib/nis/struct/boot_node_request.rb +1 -1
- data/lib/nis/struct/error.rb +1 -1
- data/lib/nis/struct/explorer_block_view_model.rb +1 -1
- data/lib/nis/struct/explorer_transfer_view_model.rb +1 -1
- data/lib/nis/struct/explorer_view_model_transaction.rb +1 -1
- data/lib/nis/struct/extended_node_experience_pair.rb +1 -1
- data/lib/nis/struct/harvest_info.rb +1 -1
- data/lib/nis/struct/key_pair_view_model.rb +1 -1
- data/lib/nis/struct/mosaic.rb +1 -1
- data/lib/nis/struct/mosaic_definition.rb +1 -1
- data/lib/nis/struct/mosaic_definition_meta_data.rb +1 -1
- data/lib/nis/struct/mosaic_definition_meta_data_pair.rb +1 -1
- data/lib/nis/struct/mosaic_id.rb +1 -1
- data/lib/nis/struct/mosaic_levy.rb +1 -1
- data/lib/nis/struct/mosaic_properties.rb +1 -1
- data/lib/nis/struct/multisig_cosignatory_modification.rb +1 -1
- data/lib/nis/struct/namespace.rb +1 -1
- data/lib/nis/struct/namespace_meta_data.rb +1 -1
- data/lib/nis/struct/namespace_meta_data_pair.rb +1 -1
- data/lib/nis/struct/nem_announce_result.rb +1 -1
- data/lib/nis/struct/nem_async_timer_visitor.rb +1 -1
- data/lib/nis/struct/nem_request_result.rb +1 -1
- data/lib/nis/struct/nis_node_info.rb +1 -1
- data/lib/nis/struct/node.rb +1 -1
- data/lib/nis/struct/node_collection.rb +1 -1
- data/lib/nis/struct/node_experience.rb +1 -1
- data/lib/nis/struct/request_announce.rb +1 -1
- data/lib/nis/struct/request_prepare_announce.rb +1 -1
- data/lib/nis/struct/time_synchronization_result.rb +1 -1
- data/lib/nis/struct/transaction.rb +4 -4
- data/lib/nis/struct/transaction_meta_data.rb +1 -1
- data/lib/nis/struct/transaction_meta_data_pair.rb +1 -1
- data/lib/nis/struct/unconfirmed_transaction_meta_data.rb +1 -1
- data/lib/nis/struct/unconfirmed_transaction_meta_data_pair.rb +1 -1
- data/lib/nis/transaction/importance_transfer.rb +1 -1
- data/lib/nis/transaction/mosaic_definition_creation.rb +1 -1
- data/lib/nis/transaction/mosaic_supply_change.rb +1 -1
- data/lib/nis/transaction/multisig.rb +1 -1
- data/lib/nis/transaction/multisig_aggregate_modification.rb +1 -1
- data/lib/nis/transaction/multisig_signature.rb +1 -1
- data/lib/nis/transaction/provision_namespace.rb +1 -1
- data/lib/nis/transaction/transfer.rb +4 -4
- data/lib/nis/unit/address.rb +19 -0
- data/lib/nis/util/convert.rb +125 -0
- data/lib/nis/util/ed25519.rb +263 -0
- data/lib/nis/util/serializer.rb +273 -0
- data/lib/nis/version.rb +1 -1
- data/nis.gemspec +1 -1
- metadata +9 -5
@@ -8,7 +8,7 @@ class Nis::Transaction
|
|
8
8
|
# @attr [Integer] version
|
9
9
|
# @attr [String] signer
|
10
10
|
# @attr [String] signature
|
11
|
-
# @see
|
11
|
+
# @see https://nemproject.github.io/#multisigAggregateModificationTransaction
|
12
12
|
class MultisigAggregateModification
|
13
13
|
include Nis::Mixin::Struct
|
14
14
|
|
@@ -8,7 +8,7 @@ class Nis::Transaction
|
|
8
8
|
# @attr [Integer] version
|
9
9
|
# @attr [String] signer
|
10
10
|
# @attr [String] signature
|
11
|
-
# @see
|
11
|
+
# @see https://nemproject.github.io/#multisigSignatureTransaction
|
12
12
|
class MultisigSignature
|
13
13
|
include Nis::Mixin::Struct
|
14
14
|
|
@@ -11,7 +11,7 @@ class Nis::Transaction
|
|
11
11
|
# @attr [String] signer
|
12
12
|
# @attr [String] signature
|
13
13
|
# @attr [Symbol] network
|
14
|
-
# @see
|
14
|
+
# @see https://nemproject.github.io/#provisionNamespaceTransaction
|
15
15
|
class ProvisionNamespace
|
16
16
|
include Nis::Mixin::Struct
|
17
17
|
|
@@ -10,10 +10,10 @@ class Nis::Transaction
|
|
10
10
|
# @attr [Integer] version
|
11
11
|
# @attr [String] signer
|
12
12
|
# @attr [Symbol] network
|
13
|
-
# @see
|
14
|
-
# @see
|
15
|
-
# @see
|
16
|
-
# @see
|
13
|
+
# @see https://nemproject.github.io/#transferTransaction
|
14
|
+
# @see https://nemproject.github.io/#initiating-a-transfer-transaction
|
15
|
+
# @see https://nemproject.github.io/#version-1-transfer-transactions
|
16
|
+
# @see https://nemproject.github.io/#version-2-transfer-transactions
|
17
17
|
class Transfer
|
18
18
|
include Nis::Mixin::Struct
|
19
19
|
|
data/lib/nis/unit/address.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base32'
|
3
|
+
require 'digest/sha3'
|
4
|
+
|
1
5
|
module Nis::Unit
|
2
6
|
# @attr [String] value
|
3
7
|
class Address
|
@@ -37,5 +41,20 @@ module Nis::Unit
|
|
37
41
|
def ==(other)
|
38
42
|
@value == other.value
|
39
43
|
end
|
44
|
+
|
45
|
+
def self.from_public_key(public_key, network = :testnet)
|
46
|
+
bin_public_key = public_key.scan(/../).map(&:hex).pack('C*')
|
47
|
+
public_key_hash = Digest::SHA3.digest(bin_public_key, 256)
|
48
|
+
ripe = OpenSSL::Digest::RIPEMD160.digest(public_key_hash)
|
49
|
+
|
50
|
+
if network == :testnet
|
51
|
+
version = "\x98".force_encoding("ASCII-8BIT") + ripe
|
52
|
+
else
|
53
|
+
version = "\x68" + ripe
|
54
|
+
end
|
55
|
+
|
56
|
+
checksum = Digest::SHA3.digest(version, 256)[0...4]
|
57
|
+
self.new(Base32.encode(version + checksum))
|
58
|
+
end
|
40
59
|
end
|
41
60
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Nis::Util
|
2
|
+
module Convert
|
3
|
+
HEX_ENCODE_ARRAY = %w[0 1 2 3 4 5 6 7 8 9 a b c d e f]
|
4
|
+
|
5
|
+
def hexlify(obj)
|
6
|
+
obj.unpack('H*').first
|
7
|
+
end
|
8
|
+
|
9
|
+
def unhexlify(obj)
|
10
|
+
obj.scan(/../).map(&:hex).pack('C*')
|
11
|
+
end
|
12
|
+
|
13
|
+
# Reversed convertion of hex to Uint8Array
|
14
|
+
# @param [String] hex
|
15
|
+
# @return [Array]
|
16
|
+
def self.hex2ua_rev(hex)
|
17
|
+
hex2ua(hex).reverse
|
18
|
+
end
|
19
|
+
|
20
|
+
# Convert hex to Uint8Array
|
21
|
+
# @param [String] hex
|
22
|
+
# @return [Array]
|
23
|
+
def self.hex2ua(hex)
|
24
|
+
hex.scan(/../).map(&:hex)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Convert an Uint8Array to hex
|
28
|
+
# @param [Uint8Array] ua - An Uint8Array
|
29
|
+
# @return [string]
|
30
|
+
def self.ua2hex(ua)
|
31
|
+
ua.map { |el| "#{HEX_ENCODE_ARRAY[el >> 4]}#{HEX_ENCODE_ARRAY[el & 0x0f]}" }.join
|
32
|
+
end
|
33
|
+
|
34
|
+
# Convert hex to string
|
35
|
+
# @param [String] hex
|
36
|
+
# @return [String]
|
37
|
+
def self.hex2a(hex)
|
38
|
+
hex.scan(/../).map { |el| el.to_i(16).chr }.join
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convert UTF-8 to hex
|
42
|
+
# @param [string] str
|
43
|
+
# @return [string]
|
44
|
+
def self.utf8_to_hex(str)
|
45
|
+
rstr2utf8(str).each_byte.map { |b| b.to_s(16) }.join
|
46
|
+
end
|
47
|
+
|
48
|
+
# // Padding helper for above function
|
49
|
+
# let strlpad = function(str, pad, len) {
|
50
|
+
# while (str.length < len) {
|
51
|
+
# str = pad + str;
|
52
|
+
# }
|
53
|
+
# return str;
|
54
|
+
# }
|
55
|
+
|
56
|
+
# Convert an Uint8Array to WordArray
|
57
|
+
# @param [Uint8Array] ua - An Uint8Array
|
58
|
+
# @param [number] uaLength - The Uint8Array length
|
59
|
+
# @return [WordArray]
|
60
|
+
def self.ua2words(ua, ua_length)
|
61
|
+
ua[0, ua_length].each_slice(4).map do |chunk|
|
62
|
+
x = chunk[0] * 0x1000000 +
|
63
|
+
chunk[1] * 0x10000 +
|
64
|
+
chunk[2] * 0x100 +
|
65
|
+
chunk[3] * 0x1
|
66
|
+
x > 0x7fffffff ? x - 0x100000000 : x
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Convert a wordArray to Uint8Array
|
71
|
+
# @param [Uint8Array] destUa - A destination Uint8Array
|
72
|
+
# @param [WordArray] cryptowords - A wordArray
|
73
|
+
# @return [Uint8Array]
|
74
|
+
def self.words2ua(words)
|
75
|
+
words.map do |v|
|
76
|
+
temp = []
|
77
|
+
v += 0x100000000 if v < 0
|
78
|
+
temp[0] = (v >> 24)
|
79
|
+
temp[1] = (v >> 16) & 0xff
|
80
|
+
temp[2] = (v >> 8) & 0xff
|
81
|
+
temp[3] = (v) & 0xff
|
82
|
+
temp
|
83
|
+
end.flatten
|
84
|
+
end
|
85
|
+
|
86
|
+
# Converts a raw javascript string into a string of single byte characters using utf8 encoding.
|
87
|
+
# This makes it easier to perform other encoding operations on the string.
|
88
|
+
# @param [String] str
|
89
|
+
# @return [String]
|
90
|
+
def self.rstr2utf8(input)
|
91
|
+
input.unpack('U*').map do |c|
|
92
|
+
case
|
93
|
+
when c < 128
|
94
|
+
c
|
95
|
+
when 128 < c && c < 2048
|
96
|
+
[((c >> 6) | 192), ((c & 63) | 128)]
|
97
|
+
else
|
98
|
+
[((c >> 12) | 224), (((c >> 6) & 63) | 128), ((c & 63) | 128)]
|
99
|
+
end
|
100
|
+
end.flatten.map(&:chr).join
|
101
|
+
end
|
102
|
+
|
103
|
+
# Does the reverse of rstr2utf8.
|
104
|
+
def utf82rstr(input)
|
105
|
+
# let output = "", i = 0, c = 0, c1 = 0, c2 = 0, c3 = 0;
|
106
|
+
# while (i < input.length) {
|
107
|
+
# c = input.charCodeAt(i);
|
108
|
+
# if (c < 128) {
|
109
|
+
# output += String.fromCharCode(c);
|
110
|
+
# i++;
|
111
|
+
# } else if ((c > 191) && (c < 224)) {
|
112
|
+
# c2 = input.charCodeAt(i + 1);
|
113
|
+
# output += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
114
|
+
# i += 2;
|
115
|
+
# } else {
|
116
|
+
# c2 = input.charCodeAt(i + 1);
|
117
|
+
# c3 = input.charCodeAt(i + 2);
|
118
|
+
# output += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
119
|
+
# i += 3;
|
120
|
+
# }
|
121
|
+
# }
|
122
|
+
# return output;
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'digest/sha3'
|
3
|
+
require 'base32'
|
4
|
+
|
5
|
+
module Nis::Util
|
6
|
+
module Ed25519
|
7
|
+
class << self
|
8
|
+
def int2byte(i)
|
9
|
+
i.chr
|
10
|
+
end
|
11
|
+
|
12
|
+
def indexbytes(buf, i)
|
13
|
+
buf[i].ord
|
14
|
+
end
|
15
|
+
|
16
|
+
def intlist2bytes(l)
|
17
|
+
l.map {|c| c.chr }.join
|
18
|
+
end
|
19
|
+
|
20
|
+
# standard implement
|
21
|
+
def H(m)
|
22
|
+
OpenSSL::Digest::SHA512.digest(m)
|
23
|
+
end
|
24
|
+
|
25
|
+
def HH(m)
|
26
|
+
Digest::SHA3.digest(m)
|
27
|
+
end
|
28
|
+
|
29
|
+
def pow2(x, p)
|
30
|
+
# """== pow(x, 2**p, q)"""
|
31
|
+
while p > 0 do
|
32
|
+
x = x * x % $q
|
33
|
+
p -= 1
|
34
|
+
end
|
35
|
+
x
|
36
|
+
end
|
37
|
+
|
38
|
+
def inv(z)
|
39
|
+
# """$= z^{-1} \mod q$, for z != 0"""
|
40
|
+
# Adapted from curve25519_athlon.c in djb's Curve25519.
|
41
|
+
z2 = z * z % $q # 2
|
42
|
+
z9 = pow2(z2, 2) * z % $q # 9
|
43
|
+
z11 = z9 * z2 % $q # 11
|
44
|
+
z2_5_0 = (z11 * z11) % $q * z9 % $q # 31 == 2^5 - 2^0
|
45
|
+
z2_10_0 = pow2(z2_5_0, 5) * z2_5_0 % $q # 2^10 - 2^0
|
46
|
+
z2_20_0 = pow2(z2_10_0, 10) * z2_10_0 % $q # ...
|
47
|
+
z2_40_0 = pow2(z2_20_0, 20) * z2_20_0 % $q
|
48
|
+
z2_50_0 = pow2(z2_40_0, 10) * z2_10_0 % $q
|
49
|
+
z2_100_0 = pow2(z2_50_0, 50) * z2_50_0 % $q
|
50
|
+
z2_200_0 = pow2(z2_100_0, 100) * z2_100_0 % $q
|
51
|
+
z2_250_0 = pow2(z2_200_0, 50) * z2_50_0 % $q # 2^250 - 2^0
|
52
|
+
pow2(z2_250_0, 5) * z11 % $q # 2^255 - 2^5 + 11 = q - 2
|
53
|
+
end
|
54
|
+
|
55
|
+
def xrecover(y)
|
56
|
+
xx = (y * y - 1) * inv($d * y * y + 1)
|
57
|
+
x = xx.to_bn.mod_exp(($q + 3) / 8, $q)
|
58
|
+
x = (x * $I) % $q if (x * x - xx) % $q != 0
|
59
|
+
x = $q - x if x % 2 != 0
|
60
|
+
x
|
61
|
+
end
|
62
|
+
|
63
|
+
def edwards_add(_P, _Q)
|
64
|
+
# This is formula sequence 'addition-add-2008-hwcd-3' from
|
65
|
+
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
66
|
+
x1, y1, z1, t1 = _P
|
67
|
+
x2, y2, z2, t2 = _Q
|
68
|
+
|
69
|
+
a = (y1 - x1) * (y2 - x2) % $q
|
70
|
+
b = (y1 + x1) * (y2 + x2) % $q
|
71
|
+
c = t1 * 2 * $d * t2 % $q
|
72
|
+
dd = z1 * 2 * z2 % $q
|
73
|
+
e = b - a
|
74
|
+
f = dd - c
|
75
|
+
g = dd + c
|
76
|
+
h = b + a
|
77
|
+
x3 = e * f
|
78
|
+
y3 = g * h
|
79
|
+
t3 = e * h
|
80
|
+
z3 = f * g
|
81
|
+
|
82
|
+
[x3 % $q, y3 % $q, z3 % $q, t3 % $q]
|
83
|
+
end
|
84
|
+
|
85
|
+
def edwards_double(_P)
|
86
|
+
# This is formula sequence 'dbl-2008-hwcd' from
|
87
|
+
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
88
|
+
x1, y1, z1, _t1 = _P
|
89
|
+
|
90
|
+
a = x1 * x1 % $q
|
91
|
+
b = y1 * y1 % $q
|
92
|
+
c = 2 * z1 * z1 % $q
|
93
|
+
# dd = -a
|
94
|
+
e = ((x1 + y1) * (x1 + y1) - a - b) % $q
|
95
|
+
g = -a + b # dd + b
|
96
|
+
f = g - c
|
97
|
+
h = -a - b # dd - b
|
98
|
+
x3 = e * f
|
99
|
+
y3 = g * h
|
100
|
+
t3 = e * h
|
101
|
+
z3 = f * g
|
102
|
+
|
103
|
+
return x3 % $q, y3 % $q, z3 % $q, t3 % $q
|
104
|
+
end
|
105
|
+
|
106
|
+
def scalarmult(_P, e)
|
107
|
+
return $ident if e == 0
|
108
|
+
_Q = scalarmult(_P, e / 2)
|
109
|
+
_Q = edwards_double(_Q)
|
110
|
+
_Q = edwards_add(_Q, _P) if e & 1
|
111
|
+
_Q
|
112
|
+
end
|
113
|
+
|
114
|
+
def make_Bpow
|
115
|
+
_P = $B
|
116
|
+
(0...253).each do |_|
|
117
|
+
$Bpow << _P
|
118
|
+
_P = edwards_double(_P)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Implements scalarmult(B, e) more efficiently.
|
123
|
+
def scalarmult_B(e)
|
124
|
+
# scalarmult(B, l) is the identity
|
125
|
+
e = e % $l
|
126
|
+
_P = $ident
|
127
|
+
(0...253).each do |i|
|
128
|
+
_P = edwards_add(_P, $Bpow[i]) if e & 1 == 1
|
129
|
+
e = e / 2
|
130
|
+
end
|
131
|
+
_P
|
132
|
+
end
|
133
|
+
|
134
|
+
def encodeint(y)
|
135
|
+
bits = (0...$b).map {|i| (y >> i) & 1}
|
136
|
+
(0...$b/8).map {|i| int2byte((0...8).inject(0) {|sum, j| sum + (bits[i * 8 + j] << j) }) }.join
|
137
|
+
end
|
138
|
+
|
139
|
+
def encodepoint(_P)
|
140
|
+
x, y, z, _t = _P
|
141
|
+
zi = inv(z)
|
142
|
+
x = (x * zi) % $q
|
143
|
+
y = (y * zi) % $q
|
144
|
+
bits = (0...$b-1).map {|i| (y >> i) & 1} + [x & 1]
|
145
|
+
(0...$b/8).map {|i| int2byte((0...8).inject(0) {|sum, j| sum + (bits[i * 8 + j] << j) }) }.join
|
146
|
+
end
|
147
|
+
|
148
|
+
def bit(h, i)
|
149
|
+
(indexbytes(h, i / 8) >> (i % 8)) & 1
|
150
|
+
end
|
151
|
+
|
152
|
+
def publickey_unsafe(sk)
|
153
|
+
h = H(sk)
|
154
|
+
a = 2 ** ($b-2) + (3...$b-2).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
155
|
+
_A = scalarmult_B(a)
|
156
|
+
return encodepoint(_A)
|
157
|
+
end
|
158
|
+
|
159
|
+
def publickey_hash_unsafe(sk)
|
160
|
+
h = HH(sk)
|
161
|
+
a = 2 ** ($b-2) + (3...$b-2).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
162
|
+
_A = scalarmult_B(a)
|
163
|
+
return encodepoint(_A)
|
164
|
+
end
|
165
|
+
|
166
|
+
def Hint(m)
|
167
|
+
h = H(m)
|
168
|
+
(0...2*$b).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
169
|
+
end
|
170
|
+
|
171
|
+
def Hint_hash(m)
|
172
|
+
h = HH(m)
|
173
|
+
(0...2*$b).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
174
|
+
end
|
175
|
+
|
176
|
+
def signature_unsafe(m, sk, pk)
|
177
|
+
h = H(sk)
|
178
|
+
a = 2 ** ($b-2) + (3...$b-2).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
179
|
+
r = Hint(
|
180
|
+
intlist2bytes(($b/8...$b/4).map {|j| indexbytes(h, j) }) + m
|
181
|
+
)
|
182
|
+
_R = scalarmult_B(r)
|
183
|
+
_S = (r + Hint(encodepoint(_R) + pk + m) * a) % $l
|
184
|
+
encodepoint(_R) + encodeint(_S)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Not safe to use with secret keys or secret data.
|
188
|
+
#
|
189
|
+
# See module docstring. This function should be used for testing only.
|
190
|
+
def signature_hash_unsafe(m, sk, pk)
|
191
|
+
h = HH(sk)
|
192
|
+
a = 2 ** ($b-2) + (3...$b-2).inject(0) {|sum, i| sum + 2 ** i * bit(h, i) }
|
193
|
+
r = Hint_hash(
|
194
|
+
intlist2bytes(($b/8...$b/4).map {|j| indexbytes(h, j) }) + m
|
195
|
+
)
|
196
|
+
_R = scalarmult_B(r)
|
197
|
+
_S = (r + Hint_hash(encodepoint(_R) + pk + m) * a) % $l
|
198
|
+
encodepoint(_R) + encodeint(_S)
|
199
|
+
end
|
200
|
+
|
201
|
+
def isoncurve(_P)
|
202
|
+
x, y, z, t = _P
|
203
|
+
(z % $q != 0 and
|
204
|
+
x * y % $q == z * t % $q and
|
205
|
+
(y * y - x * x - z * z - $d * t * t) % $q == 0)
|
206
|
+
end
|
207
|
+
|
208
|
+
def decodeint(s)
|
209
|
+
(0...$b).inject(0) {|sum, i| sum + 2 ** i * bit(s, i) }
|
210
|
+
end
|
211
|
+
|
212
|
+
def decodepoint(s)
|
213
|
+
y = (0...$b-1).inject(0) {|sum, i| 2 ** i * bit(s, i) }
|
214
|
+
x = xrecover(y)
|
215
|
+
x = $q - x if x & 1 != bit(s, $b - 1)
|
216
|
+
_P = [x, y, 1, (x * y) % $q]
|
217
|
+
raise "decoding point that is not on curve" unless isoncurve(_P)
|
218
|
+
_P
|
219
|
+
end
|
220
|
+
|
221
|
+
class SignatureMismatch < StandardError
|
222
|
+
end
|
223
|
+
|
224
|
+
# Not safe to use when any argument is secret.
|
225
|
+
#
|
226
|
+
# See module docstring. This function should be used only for
|
227
|
+
# verifying public signatures of public messages.
|
228
|
+
def checkvalid(s, m, pk)
|
229
|
+
raise "signature length is wrong" if s.size != $b / 4
|
230
|
+
raise "public-key length is wrong" if pk.size != $b / 8
|
231
|
+
|
232
|
+
# _R = decodepoint(s[:b // 8])
|
233
|
+
_R = decodepoint(s[0...$b/8])
|
234
|
+
_A = decodepoint(pk)
|
235
|
+
_S = decodeint(s[$b/8...$b/4])
|
236
|
+
h = Hint(encodepoint(_R) + pk + m)
|
237
|
+
|
238
|
+
x1, y1, z1, _t1 = _P = scalarmult_B(_S)
|
239
|
+
x2, y2, z2, _t2 = _Q = edwards_add(_R, scalarmult(_A, h))
|
240
|
+
|
241
|
+
if (!isoncurve(_P) || !isoncurve(_Q) || (x1 * z2 - x2 * z1) % q != 0 || (y1 * z2 - y2 * z1) % q != 0)
|
242
|
+
raise SignatureMismatch("signature does not pass verification")
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
$b = 256
|
248
|
+
$q = 2 ** 255 - 19
|
249
|
+
$l = 2 ** 252 + 27742317777372353535851937790883648493
|
250
|
+
|
251
|
+
$d = -121665 * self.inv(121666) % $q
|
252
|
+
$I = 2.to_bn.mod_exp(($q - 1) / 4, $q)
|
253
|
+
|
254
|
+
$By = 4 * self.inv(5)
|
255
|
+
$Bx = self.xrecover($By)
|
256
|
+
$B = [$Bx % $q, $By % $q, 1, ($Bx * $By) % $q]
|
257
|
+
$ident = [0, 1, 1, 0]
|
258
|
+
|
259
|
+
# Bpow[i] == scalarmult(B, 2**i)
|
260
|
+
$Bpow = []
|
261
|
+
self.make_Bpow
|
262
|
+
end
|
263
|
+
end
|