Module: MoneroWalletGen::Ed25519
- Defined in:
- lib/monero_wallet_gen/ed25519.rb
Constant Summary collapse
- B =
256
- Q =
2**255 - 19
- L =
2**252 + 27742317777372353535851937790883648493
Class Method Summary collapse
- .base ⇒ Object
- .bit(str, i) ⇒ Object
- .d ⇒ Object
- .decode_int(str) ⇒ Object
- .decode_point(str) ⇒ Object
- .edwards_add(p, q) ⇒ Object
- .encode_int(y) ⇒ Object
- .encode_point(p) ⇒ Object
- .encode_point_hex(p) ⇒ Object
- .expmod(base, exponent, modulus) ⇒ Object
- .ge_scalarmult(point, e) ⇒ Object
- .hash(str) ⇒ Object
- .i ⇒ Object
- .inverse(x) ⇒ Object
- .scalarmult(point, e) ⇒ Object
- .scalarmultbase(e) ⇒ Object
- .to_point(hex) ⇒ Object
- .xrecover(y) ⇒ Object
Class Method Details
.base ⇒ Object
64 65 66 67 68 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 64 def self.base by = 4 * inverse(5) bx = xrecover(by) [bx % Q,by % Q] end |
.bit(str, i) ⇒ Object
142 143 144 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 142 def self.bit(str,i) str[i / 8].ord >> (i % 8) & 1 end |
.d ⇒ Object
33 34 35 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 33 def self.d -121665 * inverse(121666) end |
.decode_int(str) ⇒ Object
171 172 173 174 175 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 171 def self.decode_int(str) (0..B).to_a.map do |i| 2**i * bit(str,i) end.sum end |
.decode_point(str) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 147 def self.decode_point(str) y = (0..B-2).to_a.map do |i| 2**i * bit(str,i) end.sum x = xrecover(y) if x & 1 != bit(str,B-1) x = Q - x end [x,y] end |
.edwards_add(p, q) ⇒ Object
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 53 def self.edwards_add(p, q) x1 = p[0] y1 = p[1] x2 = q[0] y2 = q[1] x3 = (x1*y2+x2*y1) * inverse(1+d*x1*x2*y1*y2) y3 = (y1*y2+x1*x2) * inverse(1-d*x1*x2*y1*y2) [x3 % Q,y3 % Q] end |
.encode_int(y) ⇒ Object
136 137 138 139 140 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 136 def self.encode_int(y) #TODO #bits = [(y >> i) & 1 for i in range(b)] #return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)]) end |
.encode_point(p) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 98 def self.encode_point(p) x = p[0] y = p[1] bits = (0..254).to_a.map do |i| (y >> i) & 1 end bits << (x & 1) output = [] (0..31).to_a.each do |i| sub_bits = [] (0..7).to_a.each do |j| sub_bits << (bits[i * 8 + j] << j) end output << sub_bits.sum end output.pack('C*') end |
.encode_point_hex(p) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 117 def self.encode_point_hex(p) x = p[0] y = p[1] bits = (0..254).to_a.map do |i| (y >> i) & 1 end bits << (x & 1) output = [] (0..31).to_a.each do |i| sub_bits = [] (0..7).to_a.each do |j| sub_bits << (bits[i * 8 + j] << j) end output << sub_bits.sum end output.map { |x| x.to_s(16).rjust(2, '0') }.join end |
.expmod(base, exponent, modulus) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 16 def self.expmod(base, exponent, modulus) return modulus == 1 ? 0 : begin result = 1 base = base % modulus while exponent > 0 result = result * base % modulus if exponent % 2 == 1 exponent = exponent >> 1 base = base * base % modulus end result end end |
.ge_scalarmult(point, e) ⇒ Object
94 95 96 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 94 def self.ge_scalarmult(point, e) encode_point_hex(scalarmult(to_point(point), e)) end |
.hash(str) ⇒ Object
12 13 14 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 12 def self.hash(str) Digest::SHA512.digest(str) end |
.i ⇒ Object
37 38 39 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 37 def self.i expmod(2,(Q-1)/4,Q) end |
.inverse(x) ⇒ Object
29 30 31 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 29 def self.inverse(x) expmod(x,Q-2,Q) end |
.scalarmult(point, e) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 70 def self.scalarmult(point, e) return [0,1] if e == 0 q = scalarmult(point, e / 2) q = edwards_add(q,q) if (e & 1) == 1 q = edwards_add(q,point) end q end |
.scalarmultbase(e) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 82 def self.scalarmultbase(e) return [0,1] if e == 0 q = scalarmult(base, e/2) q = edwards_add(q,q) if (e & 1) == 1 q = edwards_add(q,base) end q end |
.to_point(hex) ⇒ Object
161 162 163 164 165 166 167 168 169 |
# File 'lib/monero_wallet_gen/ed25519.rb', line 161 def self.to_point(hex) output = [] (0..hex.length-1).step(2) do |i| substr = hex[i..i+1] output << substr.to_i(16) end bin = output.pack('C*') decode_point(bin) end |