計算機科学のブログ

楕円曲線 楕円曲線上の点、等式、Goでコーディング

プログラミング・ビットコイン ―ゼロからビットコインをプログラムする方法 (Jimmy Song(著)、中川 卓俊(監修)、住田 和則(監修)、中村 昭雄(監修)、星野 靖子(翻訳)、オライリー・ジャパン)の2章(楕円曲線)、2.2(Pythonで楕円曲線をコーディング)の練習問題1、2の解答をPythonではなくGoで求めてみる。

1

4 2 = 16 2 3 + 5 · 2 + 7 = 8 + 10 + 7 = 25

よって

( 2 , 4 )

は問題の曲線上の点ではない。

( - 1 ) 2 = 1 ( - 1 ) 3 - 5 + 7 = 1

曲線上の点。

7 7 2 = 5929 1 8 3 + 5 · 18 + 7 = 5832 + 90 + 7 = 5929

曲線上の点。

7 2 = 49 5 3 + 5 · 5 + 7 = 125 + 25 + 7 49

曲線上の点ではない。

2

コード

ecc.go

// Package ecc (Elliptic Curve Cryptography, 楕円曲線暗号)
package ecc

import "fmt"

// 省略

// Point 楕円曲線 y^2 = x^3 + Ax + B上の点
type Point struct {
	A, B, X, Y int
}

// NewPoint ...
func NewPoint(x, y, a, b int) (Point, error) {
	if y*y != x*x*x+a*x+b {
		return Point{}, fmt.Errorf("(%v, %v) is not on the curve", x, y)
	}
	return Point{A: a, B: b, X: x, Y: y}, nil
}

// Eq ...
func (p Point) Eq(p1 Point) bool {
	return p.X == p1.X && p.Y == p1.Y && p.A == p1.A && p.B == p1.B
}

// Ne ...
func (p Point) Ne(p1 Point) bool {
	return !p.Eq(p1)
}

ecc_test.go

package ecc

import "testing"

// 省略

func TestPointErr(t *testing.T) {
	_, err := NewPoint(-1, -2, 5, 7)
	if err == nil {
		t.Errorf("NewPoint(-1, -1, 5, 7) got (_, nil), want (_, %v)", err)
	}
}

入出力結果

% go test
# bitcoin/ecc [bitcoin/ecc.test]
./ecc_test.go:108:12: undefined: NewPoint
FAIL	bitcoin/ecc [build failed]
% go test
PASS
ok  	bitcoin/ecc	0.221s
% go test -v
=== RUN   TestFieldElementEq
--- PASS: TestFieldElementEq (0.00s)
=== RUN   TestFieldElementNe
--- PASS: TestFieldElementNe (0.00s)
=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
=== RUN   TestSub
--- PASS: TestSub (0.00s)
=== RUN   TestMul
--- PASS: TestMul (0.00s)
=== RUN   TestDiv
--- PASS: TestDiv (0.00s)
=== RUN   TestPow
--- PASS: TestPow (0.00s)
=== RUN   TestPointErr
--- PASS: TestPointErr (0.00s)
PASS
ok  	bitcoin/ecc	0.328s
%