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

Class Method Details

.baseObject



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

.dObject



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

.iObject



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

.xrecover(y) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/monero_wallet_gen/ed25519.rb', line 41

def self.xrecover(y)
  xx = (y * y - 1) * inverse(d * y * y + 1)
  x = expmod(xx, (Q + 3) / 8, Q)
  if (x * x - xx) % Q != 0
    x = (x * i) % Q
  end
  if x % 2 != 0
    x = Q-x
  end
  x
end