{"action":"created","comment":{"url":"https://api.github.com/repos/btcsuite/btcd/pulls/comments/65760945","id":65760945,"diff_hunk":"@@ -0,0 +1,925 @@\n+// Copyright (c) 2013-2014 The btcsuite developers\n+// Copyright (c) 2013-2014 Dave Collins\n+// Use of this source code is governed by an ISC\n+// license that can be found in the LICENSE file.\n+\n+package btcec_test\n+\n+import (\n+\t\"crypto/rand\"\n+\t\"fmt\"\n+\t\"math/big\"\n+\t\"reflect\"\n+\t\"testing\"\n+\n+\t\"github.com/btcsuite/btcd/btcec\"\n+)\n+\n+// TestSetInt ensures that setting a field value to various native integers\n+// works as expected.\n+func TestNfieldSetInt(t *testing.T) {\n+\ttests := []struct {\n+\t\tin  uint\n+\t\traw [10]uint32\n+\t}{\n+\t\t{5, [10]uint32{5, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\n+\t\t// 2^26\n+\t\t{67108864, [10]uint32{67108864, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\n+\t\t// 2^26 + 1\n+\t\t{67108865, [10]uint32{67108865, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\n+\t\t// 2^32 - 1\n+\t\t{4294967295, [10]uint32{4294967295, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetInt(test.in)\n+\t\tresult := f.TstNfieldRawInts()\n+\t\tif !reflect.DeepEqual(result, test.raw) {\n+\t\t\tt.Errorf(\"nfieldVal.Set #%d wrong result\\ngot: %v\\n\"+\n+\t\t\t\t\"want: %v\", i, result, test.raw)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestZero ensures that zeroing a field value zero works as expected.\n+func TestNfieldZero(t *testing.T) {\n+\tf := btcec.NewNfieldVal().SetInt(2)\n+\tf.Zero()\n+\tfor idx, rawInt := range f.TstNfieldRawInts() {\n+\t\tif rawInt != 0 {\n+\t\t\tt.Errorf(\"internal field integer at index #%d is not \"+\n+\t\t\t\t\"zero - got %d\", idx, rawInt)\n+\t\t}\n+\t}\n+}\n+\n+// TestIsZero ensures that checking if a field IsZero works as expected.\n+func TestNfieldIsZero(t *testing.T) {\n+\tf := btcec.NewNfieldVal()\n+\tif !f.IsZero() {\n+\t\tt.Errorf(\"new field value is not zero - got %v (rawints %x)\", f,\n+\t\t\tf.TstNfieldRawInts())\n+\t}\n+\n+\tf.SetInt(1)\n+\tif f.IsZero() {\n+\t\tt.Errorf(\"field claims it's zero when it's not - got %v \"+\n+\t\t\t\"(raw rawints %x)\", f, f.TstNfieldRawInts())\n+\t}\n+\n+\tf.Zero()\n+\tif !f.IsZero() {\n+\t\tt.Errorf(\"field claims it's not zero when it is - got %v \"+\n+\t\t\t\"(raw rawints %x)\", f, f.TstNfieldRawInts())\n+\t}\n+}\n+\n+// TestStringer ensures the stringer returns the appropriate hex string.\n+func TestNfieldStringer(t *testing.T) {\n+\ttests := []struct {\n+\t\tin       string\n+\t\texpected string\n+\t}{\n+\t\t{\"0\", \"0000000000000000000000000000000000000000000000000000000000000000\"},\n+\t\t{\"1\", \"0000000000000000000000000000000000000000000000000000000000000001\"},\n+\t\t{\"a\", \"000000000000000000000000000000000000000000000000000000000000000a\"},\n+\t\t{\"b\", \"000000000000000000000000000000000000000000000000000000000000000b\"},\n+\t\t{\"c\", \"000000000000000000000000000000000000000000000000000000000000000c\"},\n+\t\t{\"d\", \"000000000000000000000000000000000000000000000000000000000000000d\"},\n+\t\t{\"e\", \"000000000000000000000000000000000000000000000000000000000000000e\"},\n+\t\t{\"f\", \"000000000000000000000000000000000000000000000000000000000000000f\"},\n+\t\t{\"f0\", \"00000000000000000000000000000000000000000000000000000000000000f0\"},\n+\t\t// 2^26-1\n+\t\t{\n+\t\t\t\"3ffffff\",\n+\t\t\t\"0000000000000000000000000000000000000000000000000000000003ffffff\",\n+\t\t},\n+\t\t// 2^32-1\n+\t\t{\n+\t\t\t\"ffffffff\",\n+\t\t\t\"00000000000000000000000000000000000000000000000000000000ffffffff\",\n+\t\t},\n+\t\t// 2^64-1\n+\t\t{\n+\t\t\t\"ffffffffffffffff\",\n+\t\t\t\"000000000000000000000000000000000000000000000000ffffffffffffffff\",\n+\t\t},\n+\t\t// 2^96-1\n+\t\t{\n+\t\t\t\"ffffffffffffffffffffffff\",\n+\t\t\t\"0000000000000000000000000000000000000000ffffffffffffffffffffffff\",\n+\t\t},\n+\t\t// 2^128-1\n+\t\t{\n+\t\t\t\"ffffffffffffffffffffffffffffffff\",\n+\t\t\t\"00000000000000000000000000000000ffffffffffffffffffffffffffffffff\",\n+\t\t},\n+\t\t// 2^160-1\n+\t\t{\n+\t\t\t\"ffffffffffffffffffffffffffffffffffffffff\",\n+\t\t\t\"000000000000000000000000ffffffffffffffffffffffffffffffffffffffff\",\n+\t\t},\n+\t\t// 2^192-1\n+\t\t{\n+\t\t\t\"ffffffffffffffffffffffffffffffffffffffffffffffff\",\n+\t\t\t\"0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff\",\n+\t\t},\n+\t\t// 2^224-1\n+\t\t{\n+\t\t\t\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n+\t\t\t\"00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n+\t\t},\n+\t\t// 2^256-432420386565659656852420866394968145599\n+\t\t// (the btcec n, so should result in 0)\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n+\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\",\n+\t\t},\n+\t\t// 2^256-432420386565659656852420866394968145599\n+\t\t// (the secp256k1 n+1, so should result in 1)\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n+\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\",\n+\t\t},\n+\n+\t\t// Invalid hex\n+\t\t{\"g\", \"0000000000000000000000000000000000000000000000000000000000000000\"},\n+\t\t{\"1h\", \"0000000000000000000000000000000000000000000000000000000000000000\"},\n+\t\t{\"i1\", \"0000000000000000000000000000000000000000000000000000000000000000\"},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in)\n+\t\tresult := f.String()\n+\t\tif result != test.expected {\n+\t\t\tt.Errorf(\"nfieldVal.String #%d wrong result\\ngot: %v\\n\"+\n+\t\t\t\t\"want: %v\", i, result, test.expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestNormalize ensures that normalizing the internal field words works as\n+// expected.\n+func TestNfieldNormalize(t *testing.T) {\n+\ttests := []struct {\n+\t\traw        [10]uint32 // Intentionally denormalized value\n+\t\tnormalized [10]uint32 // Normalized form of the raw value\n+\t}{\n+\t\t{\n+\t\t\t[10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^26\n+\t\t{\n+\t\t\t[10]uint32{0x04000000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000000, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^26 + 1\n+\t\t{\n+\t\t\t[10]uint32{0x04000001, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000001, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^32 - 1\n+\t\t{\n+\t\t\t[10]uint32{0xffffffff, 0x00, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x03ffffff, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^32\n+\t\t{\n+\t\t\t[10]uint32{0x04000000, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000000, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^32 + 1\n+\t\t{\n+\t\t\t[10]uint32{0x04000001, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000001, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^64 - 1\n+\t\t{\n+\t\t\t[10]uint32{0xffffffff, 0xffffffc0, 0xfc0, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x03ffffff, 0x03ffffff, 0xfff, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^64\n+\t\t{\n+\t\t\t[10]uint32{0x04000000, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000000, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^64 + 1\n+\t\t{\n+\t\t\t[10]uint32{0x04000001, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000001, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^96 - 1\n+\t\t{\n+\t\t\t[10]uint32{0xffffffff, 0xffffffc0, 0xffffffc0, 0x3ffc0, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x03ffffff, 0x03ffffff, 0x03ffffff, 0x3ffff, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^96\n+\t\t{\n+\t\t\t[10]uint32{0x04000000, 0x03ffffff, 0x03ffffff, 0x3ffff, 0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000000, 0x00000000, 0x00000000, 0x40000, 0, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^128 - 1\n+\t\t{\n+\t\t\t[10]uint32{0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffc0, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0xffffff, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^128\n+\t\t{\n+\t\t\t[10]uint32{0x04000000, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x0ffffff, 0, 0, 0, 0, 0},\n+\t\t\t[10]uint32{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1000000, 0, 0, 0, 0, 0},\n+\t\t},\n+\t\t// 2^256 - 432420386565659656852420866394968145599 (secp256k1 n)\n+\t\t{\n+\t\t\t[10]uint32{0xd0364141, 0xf497a300, 0x8a03bbc0, 0x739abd00, 0xfebaaec0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0x3fffc0},\n+\t\t\t[10]uint32{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000},\n+\t\t},\n+\t\t// 2^256 - 1\n+\t\t{\n+\t\t\t[10]uint32{0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0x3fffc0},\n+\t\t\t[10]uint32{0x3c9bebe, 0x3685ccb, 0x1fc4402, 0x6542dd, 0x1455123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000},\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().TstNfieldSetRawInts(test.raw).Normalize()\n+\t\tresult := f.TstNfieldRawInts()\n+\t\tif !reflect.DeepEqual(result, test.normalized) {\n+\t\t\tt.Errorf(\"nfieldVal.Set #%d wrong normalized result\\n\"+\n+\t\t\t\t\"got: %x\\nwant: %x\", i, result, test.normalized)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestIsOdd ensures that checking if a field value IsOdd works as expected.\n+func TestNfieldIsOdd(t *testing.T) {\n+\ttests := []struct {\n+\t\tin       string // hex encoded value\n+\t\texpected bool   // expected oddness\n+\t}{\n+\t\t{\"0\", false},\n+\t\t{\"1\", true},\n+\t\t{\"2\", false},\n+\t\t// 2^32 - 1\n+\t\t{\"ffffffff\", true},\n+\t\t// 2^64 - 2\n+\t\t{\"fffffffffffffffe\", false},\n+\t\t// secp256k1 n\n+\t\t{\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\", true},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in)\n+\t\tresult := f.IsOdd()\n+\t\tif result != test.expected {\n+\t\t\tt.Errorf(\"nfieldVal.IsOdd #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, test.expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestEquals ensures that checking two field values for equality via Equals\n+// works as expected.\n+func TestNfieldEquals(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // hex encoded value\n+\t\tin2      string // hex encoded value\n+\t\texpected bool   // expected equality\n+\t}{\n+\t\t{\"0\", \"0\", true},\n+\t\t{\"0\", \"1\", false},\n+\t\t{\"1\", \"0\", false},\n+\t\t// 2^32 - 1 == 2^32 - 1?\n+\t\t{\"ffffffff\", \"ffffffff\", true},\n+\t\t// 2^64 - 1 == 2^64 - 2?\n+\t\t{\"ffffffffffffffff\", \"fffffffffffffffe\", false},\n+\t\t// 0 == n (mod n)?\n+\t\t{\"0\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", true},\n+\t\t// 1 == n+1 (mod n)?\n+\t\t{\"1\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\", true},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\tf2 := btcec.NewNfieldVal().SetHex(test.in2).Normalize()\n+\t\tresult := f.Equals(f2)\n+\t\tif result != test.expected {\n+\t\t\tt.Errorf(\"nfieldVal.Equals #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, test.expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestNegate ensures that negating field values via Negate works as expected.\n+func TestNfieldNegate(t *testing.T) {\n+\ttests := []struct {\n+\t\tin       string // hex encoded value\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t// secp256k1 n (aka 0)\n+\t\t{\"0\", \"0\"},\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", \"0\"},\n+\t\t{\"0\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\"},\n+\t\t// secp256k1 n-1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\", \"1\"},\n+\t\t{\"1\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\"},\n+\t\t// secp256k1 n-2\n+\t\t{\"2\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f\"},\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f\", \"2\"},\n+\t\t{\n+\t\t\t\"1000000000000000000000000000000000000000000000000000000000000000\",\n+\t\t\t\"effffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n+\t\t},\n+\t\t{\n+\t\t\t\"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n+\t\t\t\"dffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n+\t\t},\n+\t\t// Random sampling\n+\t\t{\n+\t\t\t\"b3d9aac9c5e43910b4385b53c7e78c21d4cd5f8e683c633aed04c233efc2e120\",\n+\t\t\t\"4c2655363a1bc6ef4bc7a4ac381873dce5e17d58470c3d00d2cd9c58e0736021\",\n+\t\t},\n+\t\t{\n+\t\t\t\"f8a85984fee5a12a7c8dd08830d83423c937d77c379e4a958e447a25f407733f\",\n+\t\t\t\"0757a67b011a5ed583722f77cf27cbdaf177056a77aa55a6318de466dc2ece02\",\n+\t\t},\n+\t\t{\n+\t\t\t\"45ee6142a7fda884211e93352ed6cb2807800e419533be723a9548823ece8312\",\n+\t\t\t\"ba119ebd5802577bdee16ccad12934d6b32ecea51a14e1c9853d160a9167be2f\",\n+\t\t},\n+\t\t{\n+\t\t\t\"53c2a668f07e411a2e473e1c3b6dcb495dec1227af27673761d44afe5b43d22b\",\n+\t\t\t\"ac3d59970f81bee5d1b8c1e3c49234b55cc2cabf002139045dfe138e74f26f16\",\n+\t\t},\n+\t\t{\n+\t\t\t\"03f35d9f097eae5574e78580daa4f328bc84168e1782192f8d1a791f48b20157\",\n+\t\t\t\"fc0ca260f68151aa8b187a7f255b0cd5fe2ac65897c6870c32b7e56d87843fea\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.Negate().Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.Negate #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestAddInt ensures that adding an integer to field values via AddInt works as\n+// expected.\n+func TestNfieldAddInt(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // hex encoded value\n+\t\tin2      uint   // unsigned integer to add to the value above\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t{\"0\", 1, \"1\"},\n+\t\t{\"1\", 0, \"1\"},\n+\t\t{\"1\", 1, \"2\"},\n+\t\t// secp256k1 n-1 + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\", 1, \"0\"},\n+\t\t// secp256k1 n + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 1, \"1\"},\n+\t\t// Random samples.\n+\t\t{\n+\t\t\t\"ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d6c1\",\n+\t\t\t0x10f,\n+\t\t\t\"ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d7d0\",\n+\t\t},\n+\t\t{\n+\t\t\t\"44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41deea9cecf\",\n+\t\t\t0x2cf11d41,\n+\t\t\t\"44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41e1b9aec10\",\n+\t\t},\n+\t\t{\n+\t\t\t\"88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f7105122c9c\",\n+\t\t\t0x4829aa2d,\n+\t\t\t\"88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f714d3bd6c9\",\n+\t\t},\n+\t\t{\n+\t\t\t\"8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee09a015e2a6\",\n+\t\t\t0xa21265a5,\n+\t\t\t\"8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee0a4228484b\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.AddInt(test.in2).Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.AddInt #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestAdd ensures that adding two field values together via Add works as\n+// expected.\n+func TestNfieldAdd(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // first hex encoded value\n+\t\tin2      string // second hex encoded value to add\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t{\"0\", \"1\", \"1\"},\n+\t\t{\"1\", \"0\", \"1\"},\n+\t\t{\"1\", \"1\", \"2\"},\n+\t\t// secp256k1 n-1 + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\", \"1\", \"0\"},\n+\t\t// secp256k1 n + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", \"1\", \"1\"},\n+\t\t// Random samples.\n+\t\t{\n+\t\t\t\"2b2012f975404e5065b4292fb8bed0a5d315eacf24c74d8b27e73bcc5430edcc\",\n+\t\t\t\"2c3cefa4e4753e8aeec6ac4c12d99da4d78accefda3b7885d4c6bab46c86db92\",\n+\t\t\t\"575d029e59b58cdb547ad57bcb986e4aaaa0b7beff02c610fcadf680c0b7c95e\",\n+\t\t},\n+\t\t{\n+\t\t\t\"8131e8722fe59bb189692b96c9f38de92885730f1dd39ab025daffb94c97f79c\",\n+\t\t\t\"ff5454b765f0aab5f0977dcc629becc84cabeb9def48e79c6aadb2622c490fa9\",\n+\t\t\t\"80863d2995d646677a00a9632c8f7ab2ba8281c65dd3e210d0b6538ea8aac604\",\n+\t\t},\n+\t\t{\n+\t\t\t\"c7c95e93d0892b2b2cdd77e80eb646ea61be7a30ac7e097e9f843af73fad5c22\",\n+\t\t\t\"3afe6f91a74dfc1c7f15c34907ee981656c37236d946767dd53ccad9190e437c\",\n+\t\t\t\"02c7ce2577d72747abf33b3116a4df01fdd30f80d67bdfc0b4eea74388855e5d\",\n+\t\t},\n+\t\t{\n+\t\t\t\"fd1c26f6a23381e5d785ba889494ec059369b888ad8431cd67d8c934b580dbe1\",\n+\t\t\t\"a475aa5a31dcca90ef5b53c097d9133d6b7117474b41e7877bb199590fc0489c\",\n+\t\t\t\"a191d150d4104c76c6e10e492c6dff44442bf2e9497d791923b80400f50ae33c\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\tf2 := btcec.NewNfieldVal().SetHex(test.in2).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.Add(f2).Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.Add #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestAdd2 ensures that adding two field values together via Add2 works as\n+// expected.\n+func TestNfieldAdd2(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // first hex encoded value\n+\t\tin2      string // second hex encoded value to add\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t{\"0\", \"1\", \"1\"},\n+\t\t{\"1\", \"0\", \"1\"},\n+\t\t{\"1\", \"1\", \"2\"},\n+\t\t// secp256k1 n-1 + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\", \"1\", \"0\"},\n+\t\t// secp256k1 n + 1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", \"1\", \"1\"},\n+\t\t// Random samples.\n+\t\t{\n+\t\t\t\"ad82b8d1cc136e23e9fd77fe2c7db1fe5a2ecbfcbde59ab3529758334f862d28\",\n+\t\t\t\"4d6a4e95d6d61f4f46b528bebe152d408fd741157a28f415639347a84f6f574b\",\n+\t\t\t\"faed0767a2e98d7330b2a0bcea92df3eea060d12380e8ec8b62a9fdb9ef58473\",\n+\t\t},\n+\t\t{\n+\t\t\t\"f3f43a2540054a86e1df98547ec1c0e157b193e5350fb4a3c3ea214b228ac5e7\",\n+\t\t\t\"25706572592690ea3ddc951a1b48b504a4c83dc253756e1b96d56fdfb3199522\",\n+\t\t\t\"19649f97992bdb711fbc2d6e9a0a75e741caf4c0d93c82839aed329e056e19c8\",\n+\t\t},\n+\t\t{\n+\t\t\t\"6915bb94eef13ff1bb9b2633d997e13b9b1157c713363cc0e891416d6734f5b8\",\n+\t\t\t\"11f90d6ac6fe1c4e8900b1c85fb575c251ec31b9bc34b35ada0aea1c21eded22\",\n+\t\t\t\"7b0ec8ffb5ef5c40449bd7fc394d56fdecfd8980cf6af01bc29c2b898922e2da\",\n+\t\t},\n+\t\t{\n+\t\t\t\"48b0c9eae622eed9335b747968544eb3e75cb2dc8128388f948aa30f88cabde4\",\n+\t\t\t\"0989882b52f85f9d524a3a3061a0e01f46d597839d2ba637320f4b9510c8d2d5\",\n+\t\t\t\"523a5216391b4e7685a5aea9c9f52ed32e324a601e53dec6c699eea4999390b9\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\tf2 := btcec.NewNfieldVal().SetHex(test.in2).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.Add2(f, f2).Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.Add2 #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestMulInt ensures that adding an integer to field values via MulInt works as\n+// expected.\n+func TestNfieldMulInt(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // hex encoded value\n+\t\tin2      uint   // unsigned integer to multiply with value above\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t{\"0\", 0, \"0\"},\n+\t\t{\"1\", 0, \"0\"},\n+\t\t{\"0\", 1, \"0\"},\n+\t\t{\"1\", 1, \"1\"},\n+\t\t// secp256k1 n-1 * 2\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n+\t\t\t2,\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f\",\n+\t\t},\n+\t\t// secp256k1 n * 3\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 3, \"0\"},\n+\t\t// secp256k1 n-1 * 8\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n+\t\t\t8,\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139\",\n+\t\t},\n+\t\t// Random samples for first value.  The second value is limited\n+\t\t// to 8 since that is the maximum int used in the elliptic curve\n+\t\t// calculations.\n+\t\t{\n+\t\t\t\"b75674dc9180d306c692163ac5e089f7cef166af99645c0c23568ab6d967288a\",\n+\t\t\t6,\n+\t\t\t\"4c06bd2b6904f228a76c8560a3433bd3eeecf482db37a759d4bdc615d791ee38\",\n+\t\t},\n+\t\t{\n+\t\t\t\"54873298ac2b5ba8591c125ae54931f5ea72040aee07b208d6135476fb5b9c0e\",\n+\t\t\t3,\n+\t\t\t\"fd9597ca048212f90b543710afdb95e1bf560c20ca17161a8239fd64f212d42a\",\n+\t\t},\n+\t\t{\n+\t\t\t\"7c30fbd363a74c17e1198f56b090b59bbb6c8755a74927a6cba7a54843506401\",\n+\t\t\t5,\n+\t\t\t\"6cf4eb20f2447c77657fccb172d38c0d33c0eadee5dc85ca7aa17d4fb0257183\",\n+\t\t},\n+\t\t{\n+\t\t\t\"fb4529be3e027a3d1587d8a500b72f2d312e3577340ef5175f96d113be4c2ceb\",\n+\t\t\t8,\n+\t\t\t\"da294df1f013d1e8ac3ec52805b979726ea9a16ad57b4718bdf5f2c440e59e91\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.MulInt(test.in2).Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.MulInt #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestMul ensures that multiplying two field valuess via Mul works as expected.\n+func TestNfieldMul(t *testing.T) {\n+\ttests := []struct {\n+\t\tin1      string // first hex encoded value\n+\t\tin2      string // second hex encoded value to multiply with\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t{\"0\", \"0\", \"0\"},\n+\t\t{\"1\", \"0\", \"0\"},\n+\t\t{\"0\", \"1\", \"0\"},\n+\t\t{\"1\", \"1\", \"1\"},\n+\t\t// secp256k1 n-1 * 2\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n+\t\t\t\"2\",\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f\",\n+\t\t},\n+\t\t// secp256k1 n * 3\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n+\t\t\t\"3\",\n+\t\t\t\"0\",\n+\t\t},\n+\t\t// secp256k1 n-1 * 8\n+\t\t{\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n+\t\t\t\"8\",\n+\t\t\t\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139\",\n+\t\t},\n+\t\t// Random samples.\n+\t\t{\n+\t\t\t\"cfb81753d5ef499a98ecc04c62cb7768c2e4f1740032946db1c12e405248137e\",\n+\t\t\t\"58f355ad27b4d75fb7db0442452e732c436c1f7c5a7c4e214fa9cc031426a7d3\",\n+\t\t\t\"7a3e56db90348454f42571063ccc9a13956293a14ba03c07418b11ab36c0086d\",\n+\t\t},\n+\t\t{\n+\t\t\t\"26e9d61d1cdf3920e9928e85fa3df3e7556ef9ab1d14ec56d8b4fc8ed37235bf\",\n+\t\t\t\"2dfc4bbe537afee979c644f8c97b31e58be5296d6dbc460091eae630c98511cf\",\n+\t\t\t\"f8592ec43b9f42b914be9ec641a89a58ad0d62c00e8d86640559b8d5ae91d33f\",\n+\t\t},\n+\t\t{\n+\t\t\t\"5db64ed5afb71646c8b231585d5b2bf7e628590154e0854c4c29920b999ff351\",\n+\t\t\t\"279cfae5eea5d09ade8e6a7409182f9de40981bc31c84c3d3dfe1d933f152e9a\",\n+\t\t\t\"89f90fd64b0d7579444dfbb2745dfdda883893f848f5743faca560901d8b89dd\",\n+\t\t},\n+\t\t{\n+\t\t\t\"b66dfc1f96820b07d2bdbd559c19319a3a73c97ceb7b3d662f4fe75ecb6819e6\",\n+\t\t\t\"bf774aba43e3e49eb63a6e18037d1118152568f1a3ac4ec8b89aeb6ff8008ae1\",\n+\t\t\t\"5a2590e74896908bf295a7ee473e06048c961c4fbe39d812ab0298ecd3241415\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in1).Normalize()\n+\t\tf2 := btcec.NewNfieldVal().SetHex(test.in2).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.Mul(f2).Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.Mul #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestNfieldMulRand tests the multiplication correctness by doing the\n+// same calculation with Big.Int\n+func TestNfieldMulRand(t *testing.T) {\n+\tdata := make([]byte, 32)\n+\t_, err := rand.Read(data)\n+\tif err != nil {\n+\t\tt.Fatalf(\"failed to read random data\")\n+\t}\n+\tN := btcec.S256().N\n+\ta := new(big.Int).SetBytes(data)\n+\taN := btcec.NewNfieldVal().SetByteSlice(a.Bytes())\n+\tfor i := 0; i < 100; i++ {\n+\t\tdata = make([]byte, 32)\n+\t\t_, err := rand.Read(data)\n+\t\tif err != nil {\n+\t\t\tt.Errorf(\"failed to read random data\")\n+\t\t\tcontinue\n+\t\t}\n+\t\tb := new(big.Int).SetBytes(data)\n+\t\tc := big.NewInt(0)\n+\t\tc.Mul(a, b)\n+\t\tc.Mod(c, N)\n+\t\tbN := btcec.NewNfieldVal().SetByteSlice(b.Bytes())\n+\t\tcN := btcec.NewNfieldVal()\n+\t\tcN.Mul2(aN, bN)\n+\t\tcstr := fmt.Sprintf(\"%064x\", c)\n+\t\tif cN.String() != cstr {\n+\t\t\tt.Fatalf(\"expected strings to be the same, was not: %v %v\", cN.String(), cstr)\n+\t\t}\n+\t\ta = c\n+\t\taN = cN\n+\t}\n+\n+}\n+\n+// TestSquare ensures that squaring field values via Square works as expected.\n+func TestNfieldSquare(t *testing.T) {\n+\ttests := []struct {\n+\t\tin       string // hex encoded value\n+\t\texpected string // expected hex encoded value\n+\t}{\n+\t\t// secp256k1 n (aka 0)\n+\t\t{\"0\", \"0\"},\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", \"0\"},\n+\t\t{\"0\", \"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\"},\n+\t\t// secp256k1 n-1\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\", \"1\"},\n+\t\t// secp256k1 n-2\n+\t\t{\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f\", \"4\"},\n+\t\t// Random sampling\n+\t\t{\n+\t\t\t\"b0ba920360ea8436a216128047aab9766d8faf468895eb5090fc8241ec758896\",\n+\t\t\t\"238864ca0f8b0b22a8e5ddb784a414a14def40bf7d47ba8b332644644b41031d\",\n+\t\t},\n+\t\t{\n+\t\t\t\"c55d0d730b1d0285a1599995938b042a756e6e8857d390165ffab480af61cbd5\",\n+\t\t\t\"79cd3b999f52d0f0c6af75778a936df43849848b237f14e5766ec997d49028db\",\n+\t\t},\n+\t\t{\n+\t\t\t\"e89c1f9a70d93651a1ba4bca5b78658f00de65a66014a25544d3365b0ab82324\",\n+\t\t\t\"e94d8a27a7391e5d7526c94d7b5957f0f7deb38d09644e79de1e872e71c6939b\",\n+\t\t},\n+\t\t{\n+\t\t\t\"7dc26186079d22bcbe1614aa20ae627e62d72f9be7ad1e99cac0feb438956f05\",\n+\t\t\t\"e8cdfb0f04e713f11e438275b233292d1876b2dd6e84ec850d41d8c604391b39\",\n+\t\t},\n+\t}\n+\n+\tt.Logf(\"Running %d tests\", len(tests))\n+\tfor i, test := range tests {\n+\t\tf := btcec.NewNfieldVal().SetHex(test.in).Normalize()\n+\t\texpected := btcec.NewNfieldVal().SetHex(test.expected).Normalize()\n+\t\tresult := f.Square().Normalize()\n+\t\tif !result.Equals(expected) {\n+\t\t\tt.Errorf(\"nfieldVal.Square #%d wrong result\\n\"+\n+\t\t\t\t\"got: %v\\nwant: %v\", i, result, expected)\n+\t\t\tcontinue\n+\t\t}\n+\t}\n+}\n+\n+// TestNfieldSquareRand tests the square correctness by doing the\n+// same calculation with Big.Int\n+func TestNfieldSquareRand(t *testing.T) {\n+\tdata := make([]byte, 32)\n+\t_, err := rand.Read(data)\n+\tif err != nil {\n+\t\tt.Fatalf(\"failed to read random data\")\n+\t}\n+\tN := btcec.S256().N\n+\ta := new(big.Int).SetBytes(data)\n+\taN := btcec.NewNfieldVal().SetByteSlice(a.Bytes())\n+\tfor i := 0; i < 100; i++ {\n+\t\tc := big.NewInt(0)\n+\t\tc.Mul(a, a)\n+\t\tc.Mod(c, N)\n+\t\tcN := btcec.NewNfieldVal()\n+\t\tcN.SquareVal(aN)\n+\t\tcstr := fmt.Sprintf(\"%064x\", c)\n+\t\tif cN.String() != cstr {\n+\t\t\tt.Fatalf(\"expected strings to be the same, was not: %v %v\", cN.String(), cstr)","path":"btcec/nfield_test.go","position":768,"original_position":768,"commit_id":"ea75bce77c4543b7c5eb1d5c0f7b2eb84f46b56c","original_commit_id":"ea75bce77c4543b7c5eb1d5c0f7b2eb84f46b56c","user":{"login":"davecgh","id":2115102,"avatar_url":"https://avatars.githubusercontent.com/u/2115102?v=3","gravatar_id":"","url":"https://api.github.com/users/davecgh","html_url":"https://github.com/davecgh","followers_url":"https://api.github.com/users/davecgh/followers","following_url":"https://api.github.com/users/davecgh/following{/other_user}","gists_url":"https://api.github.com/users/davecgh/gists{/gist_id}","starred_url":"https://api.github.com/users/davecgh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecgh/subscriptions","organizations_url":"https://api.github.com/users/davecgh/orgs","repos_url":"https://api.github.com/users/davecgh/repos","events_url":"https://api.github.com/users/davecgh/events{/privacy}","received_events_url":"https://api.github.com/users/davecgh/received_events","type":"User","site_admin":false},"body":"Same thing here regarding the random numbers and debugability.","created_at":"2016-06-03T19:12:33Z","updated_at":"2016-06-03T19:12:33Z","html_url":"https://github.com/btcsuite/btcd/pull/621#discussion_r65760945","pull_request_url":"https://api.github.com/repos/btcsuite/btcd/pulls/621","_links":{"self":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/comments/65760945"},"html":{"href":"https://github.com/btcsuite/btcd/pull/621#discussion_r65760945"},"pull_request":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/621"}}},"pull_request":{"url":"https://api.github.com/repos/btcsuite/btcd/pulls/621","id":58843452,"html_url":"https://github.com/btcsuite/btcd/pull/621","diff_url":"https://github.com/btcsuite/btcd/pull/621.diff","patch_url":"https://github.com/btcsuite/btcd/pull/621.patch","issue_url":"https://api.github.com/repos/btcsuite/btcd/issues/621","number":621,"state":"open","locked":false,"title":"Faster operations on the elliptical curve exponent by using nfield instead of big.Int","user":{"login":"jimmysong","id":524761,"avatar_url":"https://avatars.githubusercontent.com/u/524761?v=3","gravatar_id":"","url":"https://api.github.com/users/jimmysong","html_url":"https://github.com/jimmysong","followers_url":"https://api.github.com/users/jimmysong/followers","following_url":"https://api.github.com/users/jimmysong/following{/other_user}","gists_url":"https://api.github.com/users/jimmysong/gists{/gist_id}","starred_url":"https://api.github.com/users/jimmysong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimmysong/subscriptions","organizations_url":"https://api.github.com/users/jimmysong/orgs","repos_url":"https://api.github.com/users/jimmysong/repos","events_url":"https://api.github.com/users/jimmysong/events{/privacy}","received_events_url":"https://api.github.com/users/jimmysong/received_events","type":"User","site_admin":false},"body":"\n\n<!-- Reviewable:start -->\n[<img src=\"https://reviewable.io/review_button.svg\" height=\"40\" alt=\"Review on Reviewable\"/>](https://reviewable.io/reviews/btcsuite/btcd/621)\n<!-- Reviewable:end -->\n","created_at":"2016-02-10T03:21:40Z","updated_at":"2016-06-03T19:12:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e5d949e353979b0628db5813401035e1fb91bcb7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/btcsuite/btcd/pulls/621/commits","review_comments_url":"https://api.github.com/repos/btcsuite/btcd/pulls/621/comments","review_comment_url":"https://api.github.com/repos/btcsuite/btcd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/btcsuite/btcd/issues/621/comments","statuses_url":"https://api.github.com/repos/btcsuite/btcd/statuses/ea75bce77c4543b7c5eb1d5c0f7b2eb84f46b56c","head":{"label":"jimmysong:nfield","ref":"nfield","sha":"ea75bce77c4543b7c5eb1d5c0f7b2eb84f46b56c","user":{"login":"jimmysong","id":524761,"avatar_url":"https://avatars.githubusercontent.com/u/524761?v=3","gravatar_id":"","url":"https://api.github.com/users/jimmysong","html_url":"https://github.com/jimmysong","followers_url":"https://api.github.com/users/jimmysong/followers","following_url":"https://api.github.com/users/jimmysong/following{/other_user}","gists_url":"https://api.github.com/users/jimmysong/gists{/gist_id}","starred_url":"https://api.github.com/users/jimmysong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimmysong/subscriptions","organizations_url":"https://api.github.com/users/jimmysong/orgs","repos_url":"https://api.github.com/users/jimmysong/repos","events_url":"https://api.github.com/users/jimmysong/events{/privacy}","received_events_url":"https://api.github.com/users/jimmysong/received_events","type":"User","site_admin":false},"repo":{"id":17149918,"name":"btcd","full_name":"jimmysong/btcd","owner":{"login":"jimmysong","id":524761,"avatar_url":"https://avatars.githubusercontent.com/u/524761?v=3","gravatar_id":"","url":"https://api.github.com/users/jimmysong","html_url":"https://github.com/jimmysong","followers_url":"https://api.github.com/users/jimmysong/followers","following_url":"https://api.github.com/users/jimmysong/following{/other_user}","gists_url":"https://api.github.com/users/jimmysong/gists{/gist_id}","starred_url":"https://api.github.com/users/jimmysong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimmysong/subscriptions","organizations_url":"https://api.github.com/users/jimmysong/orgs","repos_url":"https://api.github.com/users/jimmysong/repos","events_url":"https://api.github.com/users/jimmysong/events{/privacy}","received_events_url":"https://api.github.com/users/jimmysong/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jimmysong/btcd","description":"An alternative full node bitcoin implementation written in Go (golang)","fork":true,"url":"https://api.github.com/repos/jimmysong/btcd","forks_url":"https://api.github.com/repos/jimmysong/btcd/forks","keys_url":"https://api.github.com/repos/jimmysong/btcd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jimmysong/btcd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jimmysong/btcd/teams","hooks_url":"https://api.github.com/repos/jimmysong/btcd/hooks","issue_events_url":"https://api.github.com/repos/jimmysong/btcd/issues/events{/number}","events_url":"https://api.github.com/repos/jimmysong/btcd/events","assignees_url":"https://api.github.com/repos/jimmysong/btcd/assignees{/user}","branches_url":"https://api.github.com/repos/jimmysong/btcd/branches{/branch}","tags_url":"https://api.github.com/repos/jimmysong/btcd/tags","blobs_url":"https://api.github.com/repos/jimmysong/btcd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jimmysong/btcd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jimmysong/btcd/git/refs{/sha}","trees_url":"https://api.github.com/repos/jimmysong/btcd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jimmysong/btcd/statuses/{sha}","languages_url":"https://api.github.com/repos/jimmysong/btcd/languages","stargazers_url":"https://api.github.com/repos/jimmysong/btcd/stargazers","contributors_url":"https://api.github.com/repos/jimmysong/btcd/contributors","subscribers_url":"https://api.github.com/repos/jimmysong/btcd/subscribers","subscription_url":"https://api.github.com/repos/jimmysong/btcd/subscription","commits_url":"https://api.github.com/repos/jimmysong/btcd/commits{/sha}","git_commits_url":"https://api.github.com/repos/jimmysong/btcd/git/commits{/sha}","comments_url":"https://api.github.com/repos/jimmysong/btcd/comments{/number}","issue_comment_url":"https://api.github.com/repos/jimmysong/btcd/issues/comments{/number}","contents_url":"https://api.github.com/repos/jimmysong/btcd/contents/{+path}","compare_url":"https://api.github.com/repos/jimmysong/btcd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jimmysong/btcd/merges","archive_url":"https://api.github.com/repos/jimmysong/btcd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jimmysong/btcd/downloads","issues_url":"https://api.github.com/repos/jimmysong/btcd/issues{/number}","pulls_url":"https://api.github.com/repos/jimmysong/btcd/pulls{/number}","milestones_url":"https://api.github.com/repos/jimmysong/btcd/milestones{/number}","notifications_url":"https://api.github.com/repos/jimmysong/btcd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jimmysong/btcd/labels{/name}","releases_url":"https://api.github.com/repos/jimmysong/btcd/releases{/id}","deployments_url":"https://api.github.com/repos/jimmysong/btcd/deployments","created_at":"2014-02-24T20:38:00Z","updated_at":"2015-02-27T19:38:31Z","pushed_at":"2016-02-10T03:57:17Z","git_url":"git://github.com/jimmysong/btcd.git","ssh_url":"git@github.com:jimmysong/btcd.git","clone_url":"https://github.com/jimmysong/btcd.git","svn_url":"https://github.com/jimmysong/btcd","homepage":null,"size":9292,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"btcsuite:master","ref":"master","sha":"d759d1d3df441bb81972ba9238fc80053af5fa25","user":{"login":"btcsuite","id":10235229,"avatar_url":"https://avatars.githubusercontent.com/u/10235229?v=3","gravatar_id":"","url":"https://api.github.com/users/btcsuite","html_url":"https://github.com/btcsuite","followers_url":"https://api.github.com/users/btcsuite/followers","following_url":"https://api.github.com/users/btcsuite/following{/other_user}","gists_url":"https://api.github.com/users/btcsuite/gists{/gist_id}","starred_url":"https://api.github.com/users/btcsuite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btcsuite/subscriptions","organizations_url":"https://api.github.com/users/btcsuite/orgs","repos_url":"https://api.github.com/users/btcsuite/repos","events_url":"https://api.github.com/users/btcsuite/events{/privacy}","received_events_url":"https://api.github.com/users/btcsuite/received_events","type":"Organization","site_admin":false},"repo":{"id":11931032,"name":"btcd","full_name":"btcsuite/btcd","owner":{"login":"btcsuite","id":10235229,"avatar_url":"https://avatars.githubusercontent.com/u/10235229?v=3","gravatar_id":"","url":"https://api.github.com/users/btcsuite","html_url":"https://github.com/btcsuite","followers_url":"https://api.github.com/users/btcsuite/followers","following_url":"https://api.github.com/users/btcsuite/following{/other_user}","gists_url":"https://api.github.com/users/btcsuite/gists{/gist_id}","starred_url":"https://api.github.com/users/btcsuite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btcsuite/subscriptions","organizations_url":"https://api.github.com/users/btcsuite/orgs","repos_url":"https://api.github.com/users/btcsuite/repos","events_url":"https://api.github.com/users/btcsuite/events{/privacy}","received_events_url":"https://api.github.com/users/btcsuite/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/btcsuite/btcd","description":"An alternative full node bitcoin implementation written in Go (golang)","fork":false,"url":"https://api.github.com/repos/btcsuite/btcd","forks_url":"https://api.github.com/repos/btcsuite/btcd/forks","keys_url":"https://api.github.com/repos/btcsuite/btcd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/btcsuite/btcd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/btcsuite/btcd/teams","hooks_url":"https://api.github.com/repos/btcsuite/btcd/hooks","issue_events_url":"https://api.github.com/repos/btcsuite/btcd/issues/events{/number}","events_url":"https://api.github.com/repos/btcsuite/btcd/events","assignees_url":"https://api.github.com/repos/btcsuite/btcd/assignees{/user}","branches_url":"https://api.github.com/repos/btcsuite/btcd/branches{/branch}","tags_url":"https://api.github.com/repos/btcsuite/btcd/tags","blobs_url":"https://api.github.com/repos/btcsuite/btcd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/btcsuite/btcd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/btcsuite/btcd/git/refs{/sha}","trees_url":"https://api.github.com/repos/btcsuite/btcd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/btcsuite/btcd/statuses/{sha}","languages_url":"https://api.github.com/repos/btcsuite/btcd/languages","stargazers_url":"https://api.github.com/repos/btcsuite/btcd/stargazers","contributors_url":"https://api.github.com/repos/btcsuite/btcd/contributors","subscribers_url":"https://api.github.com/repos/btcsuite/btcd/subscribers","subscription_url":"https://api.github.com/repos/btcsuite/btcd/subscription","commits_url":"https://api.github.com/repos/btcsuite/btcd/commits{/sha}","git_commits_url":"https://api.github.com/repos/btcsuite/btcd/git/commits{/sha}","comments_url":"https://api.github.com/repos/btcsuite/btcd/comments{/number}","issue_comment_url":"https://api.github.com/repos/btcsuite/btcd/issues/comments{/number}","contents_url":"https://api.github.com/repos/btcsuite/btcd/contents/{+path}","compare_url":"https://api.github.com/repos/btcsuite/btcd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/btcsuite/btcd/merges","archive_url":"https://api.github.com/repos/btcsuite/btcd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/btcsuite/btcd/downloads","issues_url":"https://api.github.com/repos/btcsuite/btcd/issues{/number}","pulls_url":"https://api.github.com/repos/btcsuite/btcd/pulls{/number}","milestones_url":"https://api.github.com/repos/btcsuite/btcd/milestones{/number}","notifications_url":"https://api.github.com/repos/btcsuite/btcd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/btcsuite/btcd/labels{/name}","releases_url":"https://api.github.com/repos/btcsuite/btcd/releases{/id}","deployments_url":"https://api.github.com/repos/btcsuite/btcd/deployments","created_at":"2013-08-06T18:10:52Z","updated_at":"2016-06-03T16:13:53Z","pushed_at":"2016-06-01T21:14:36Z","git_url":"git://github.com/btcsuite/btcd.git","ssh_url":"git@github.com:btcsuite/btcd.git","clone_url":"https://github.com/btcsuite/btcd.git","svn_url":"https://github.com/btcsuite/btcd","homepage":"https://github.com/btcsuite/btcd/blob/master/docs/README.md","size":17087,"stargazers_count":844,"watchers_count":844,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":216,"mirror_url":null,"open_issues_count":59,"forks":216,"open_issues":59,"watchers":844,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/621"},"html":{"href":"https://github.com/btcsuite/btcd/pull/621"},"issue":{"href":"https://api.github.com/repos/btcsuite/btcd/issues/621"},"comments":{"href":"https://api.github.com/repos/btcsuite/btcd/issues/621/comments"},"review_comments":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/621/comments"},"review_comment":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/btcsuite/btcd/pulls/621/commits"},"statuses":{"href":"https://api.github.com/repos/btcsuite/btcd/statuses/ea75bce77c4543b7c5eb1d5c0f7b2eb84f46b56c"}}}}
{"actor":{"display_login":"davecgh"}}