You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
11 KiB

5 years ago
5 years ago
5 years ago
  1. package merkletree
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "strconv"
  6. "testing"
  7. "time"
  8. "github.com/dchest/uniuri"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/syndtr/goleveldb/leveldb"
  11. )
  12. type testBase struct {
  13. Length [4]byte
  14. Namespace Hash
  15. Type Hash
  16. Version uint32
  17. }
  18. type testLeaf struct {
  19. testBase
  20. extraIndex struct {
  21. Data []byte
  22. }
  23. }
  24. func parseTestLeafBytes(b []byte) testLeaf {
  25. var c testLeaf
  26. copy(c.testBase.Length[:], b[0:4])
  27. copy(c.testBase.Namespace[:], b[4:36])
  28. copy(c.testBase.Type[:], b[36:68])
  29. versionBytes := b[68:72]
  30. c.testBase.Version = BytesToUint32(versionBytes)
  31. c.extraIndex.Data = b[72:]
  32. return c
  33. }
  34. func (c testLeaf) Bytes() (b []byte) {
  35. b = append(b, c.testBase.Length[:]...)
  36. b = append(b, c.testBase.Namespace[:]...)
  37. b = append(b, c.testBase.Type[:]...)
  38. versionBytes := Uint32ToBytes(c.testBase.Version)
  39. b = append(b, versionBytes[:]...)
  40. b = append(b, c.extraIndex.Data[:]...)
  41. return b
  42. }
  43. func (c testLeaf) IndexLength() uint32 {
  44. return uint32(len(c.Bytes()))
  45. }
  46. func (c testLeaf) hi() Hash {
  47. h := HashBytes(c.Bytes())
  48. return h
  49. }
  50. func newTestLeaf(namespaceStr, typeStr string, data []byte) testLeaf {
  51. var c testLeaf
  52. c.testBase.Length = [4]byte{0x00, 0x00, 0x00, 0x48}
  53. c.testBase.Namespace = HashBytes([]byte(namespaceStr))
  54. c.testBase.Type = HashBytes([]byte(typeStr))
  55. c.testBase.Version = 0
  56. c.extraIndex.Data = data
  57. return c
  58. }
  59. type Fatalable interface {
  60. Fatal(args ...interface{})
  61. }
  62. func newTestingMerkle(f Fatalable, numLevels int) *MerkleTree {
  63. tim := time.Now().Unix()
  64. tstr := fmt.Sprint(tim)
  65. s := uniuri.New()
  66. db, err := leveldb.OpenFile("tmp/db"+s+"-"+tstr, nil)
  67. if err != nil {
  68. f.Fatal(err)
  69. return nil
  70. }
  71. // defer db.Close()
  72. mt, err := New(db, numLevels)
  73. if err != nil {
  74. f.Fatal(err)
  75. return nil
  76. }
  77. return mt
  78. }
  79. func TestNewMT(t *testing.T) {
  80. //create a new MT
  81. mt := newTestingMerkle(t, 140)
  82. defer mt.storage.Close()
  83. assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", mt.Root().Hex())
  84. }
  85. func TestAddLeaf(t *testing.T) {
  86. mt := newTestingMerkle(t, 140)
  87. defer mt.storage.Close()
  88. leaf := newTestLeaf("iden3.io", "typespec", []byte("c1"))
  89. assert.Equal(t, "0x939862c94ca9772fc9e2621df47128b1d4041b514e19edc969a92d8f0dae558f", leaf.hi().Hex())
  90. assert.Nil(t, mt.Add(leaf))
  91. assert.Equal(t, "0x9d3c407ff02c813cd474c0a6366b4f7c58bf417a38268f7a0d73a8bca2490b9b", mt.Root().Hex())
  92. }
  93. func TestAddLeafs(t *testing.T) {
  94. mt := newTestingMerkle(t, 140)
  95. defer mt.storage.Close()
  96. leaf := newTestLeaf("iden3.io", "typespec", []byte("c1"))
  97. assert.Equal(t, "0x939862c94ca9772fc9e2621df47128b1d4041b514e19edc969a92d8f0dae558f", leaf.hi().Hex())
  98. assert.Nil(t, mt.Add(leaf))
  99. assert.Nil(t, mt.Add(newTestLeaf("iden3.io2", "typespec2", []byte("c2"))))
  100. assert.Equal(t, "0xebae8fb483b48ba6c337136535198eb8bcf891daba40ac81e28958c09b9b229b", mt.Root().Hex())
  101. mt.Add(newTestLeaf("iden3.io3", "typespec3", []byte("c3")))
  102. mt.Add(newTestLeaf("iden3.io4", "typespec4", []byte("c4")))
  103. assert.Equal(t, "0xb4b51aa0c77a8e5ed0a099d7c11c7d2a9219ef241da84f0689da1f40a5f6ac31", mt.Root().Hex())
  104. }
  105. func TestAddLeafsCollision(t *testing.T) {
  106. mt := newTestingMerkle(t, 140)
  107. defer mt.storage.Close()
  108. leaf := newTestLeaf("iden3.io", "typespec", []byte("c1"))
  109. assert.Nil(t, mt.Add(leaf))
  110. root1 := mt.Root()
  111. assert.EqualError(t, mt.Add(leaf), ErrNodeAlreadyExists.Error())
  112. assert.Equal(t, root1.Hex(), mt.Root().Hex())
  113. }
  114. func TestAddLeafsDifferentOrders(t *testing.T) {
  115. mt1 := newTestingMerkle(t, 140)
  116. defer mt1.storage.Close()
  117. mt1.Add(newTestLeaf("iden3.io", "typespec", []byte("c1")))
  118. mt1.Add(newTestLeaf("iden3.io2", "typespec2", []byte("c2")))
  119. mt1.Add(newTestLeaf("iden3.io3", "typespec3", []byte("c3")))
  120. mt1.Add(newTestLeaf("iden3.io4", "typespec4", []byte("c4")))
  121. mt1.Add(newTestLeaf("iden3.io5", "typespec5", []byte("c5")))
  122. mt2 := newTestingMerkle(t, 140)
  123. defer mt2.storage.Close()
  124. mt2.Add(newTestLeaf("iden3.io3", "typespec3", []byte("c3")))
  125. mt2.Add(newTestLeaf("iden3.io2", "typespec2", []byte("c2")))
  126. mt2.Add(newTestLeaf("iden3.io", "typespec", []byte("c1")))
  127. mt2.Add(newTestLeaf("iden3.io4", "typespec4", []byte("c4")))
  128. mt2.Add(newTestLeaf("iden3.io5", "typespec5", []byte("c5")))
  129. assert.Equal(t, mt1.Root().Hex(), mt2.Root().Hex())
  130. }
  131. func TestBenchmarkAddingLeafs(t *testing.T) {
  132. mt := newTestingMerkle(t, 140)
  133. defer mt.storage.Close()
  134. start := time.Now()
  135. numToAdd := 1000
  136. for i := 0; i < numToAdd; i++ {
  137. leaf := newTestLeaf("iden3.io"+strconv.Itoa(i), "typespec"+strconv.Itoa(i), []byte("c"+strconv.Itoa(i)))
  138. mt.Add(leaf)
  139. }
  140. fmt.Print("time elapsed adding " + strconv.Itoa(numToAdd) + " leafs: ")
  141. fmt.Println(time.Since(start))
  142. }
  143. func BenchmarkAddingLeafs(b *testing.B) {
  144. mt := newTestingMerkle(b, 140)
  145. defer mt.storage.Close()
  146. b.ResetTimer()
  147. for i := 0; i < b.N; i++ {
  148. leaf := newTestLeaf("iden3.io"+strconv.Itoa(i), "typespec"+strconv.Itoa(i), []byte("c"+strconv.Itoa(i)))
  149. if err := mt.Add(leaf); err != nil {
  150. b.Fatal(err)
  151. }
  152. }
  153. }
  154. func TestGenerateProof(t *testing.T) {
  155. mt := newTestingMerkle(t, 140)
  156. defer mt.storage.Close()
  157. mt.Add(newTestLeaf("iden3.io_3", "typespec_3", []byte("c3")))
  158. mt.Add(newTestLeaf("iden3.io_2", "typespec_2", []byte("c2")))
  159. leaf1 := newTestLeaf("iden3.io_1", "typespec_1", []byte("c1"))
  160. assert.Nil(t, mt.Add(leaf1))
  161. mp, err := mt.GenerateProof(parseTestLeafBytes(leaf1.Bytes()).hi())
  162. assert.Nil(t, err)
  163. mpHexExpected := "0000000000000000000000000000000000000000000000000000000000000002beb0fd6dcf18d37fe51cf34beacd4c524d9c039ef9da2a27ccd3e7edf662c39c"
  164. assert.Equal(t, mpHexExpected, hex.EncodeToString(mp))
  165. }
  166. func TestCheckProof(t *testing.T) {
  167. mt := newTestingMerkle(t, 140)
  168. defer mt.storage.Close()
  169. leaf1 := newTestLeaf("iden3.io_1", "typespec_1", []byte("c1"))
  170. assert.Nil(t, mt.Add(leaf1))
  171. leaf3 := newTestLeaf("iden3.io_3", "typespec_3", []byte("c3"))
  172. assert.Nil(t, mt.Add(leaf3))
  173. mp, err := mt.GenerateProof(parseTestLeafBytes(leaf1.Bytes()).hi())
  174. assert.Nil(t, err)
  175. verified := CheckProof(mt.Root(), mp, leaf1.hi(), HashBytes(leaf1.Bytes()), mt.NumLevels())
  176. assert.True(t, verified)
  177. }
  178. func TestProofOfEmpty(t *testing.T) { // proof of a non revocated leaf, prove that is empty the hi position of the leaf.version+1
  179. mt := newTestingMerkle(t, 140)
  180. defer mt.storage.Close()
  181. leaf1 := newTestLeaf("iden3.io_1", "typespec_1", []byte("c1"))
  182. // proof when there is nothing in the tree
  183. mp, err := mt.GenerateProof(leaf1.hi())
  184. assert.Nil(t, err)
  185. verified := CheckProof(mt.Root(), mp, leaf1.hi(), EmptyNodeValue, mt.NumLevels())
  186. assert.True(t, verified)
  187. // add the first leaf
  188. assert.Nil(t, mt.Add(leaf1))
  189. // proof when there is only one leaf in the tree
  190. leaf2 := newTestLeaf("iden3.io_2", "typespec_2", []byte("c2"))
  191. mp, err = mt.GenerateProof(leaf2.hi())
  192. assert.Nil(t, err)
  193. verified = CheckProof(mt.Root(), mp, leaf2.hi(), EmptyNodeValue, mt.NumLevels())
  194. assert.True(t, verified)
  195. // check that the value in Hi is Empty
  196. valueInPos, err := mt.GetValueInPos(leaf2.hi())
  197. assert.Nil(t, err)
  198. assert.Equal(t, EmptyNodeValue.Bytes(), valueInPos)
  199. }
  200. func DifferentNonExistenceProofs(t *testing.T) {
  201. mt1 := newTestingMerkle(t, 140)
  202. defer mt1.storage.Close()
  203. mt2 := newTestingMerkle(t, 140)
  204. defer mt2.storage.Close()
  205. leaf1 := newTestLeaf("iden3.io_1", "typespec_1", []byte("c1"))
  206. leaf2 := newTestLeaf("iden3.io_1", "typespec_1", []byte("c2"))
  207. assert.Nil(t, mt1.Add(leaf1))
  208. assert.Nil(t, mt2.Add(leaf2))
  209. leaf1.Version++
  210. leaf2.Version++
  211. np1, err := mt1.GenerateProof(leaf1.hi())
  212. assert.Nil(t, err)
  213. np2, err := mt2.GenerateProof(leaf2.hi())
  214. assert.Nil(t, err)
  215. assert.True(t, CheckProof(mt1.Root(), np1, leaf1.hi(), EmptyNodeValue, mt1.NumLevels()))
  216. assert.True(t, CheckProof(mt2.Root(), np2, leaf2.hi(), EmptyNodeValue, mt2.NumLevels()))
  217. assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000010a40617c8c3390736831d00b2003e2133353190f5d3b3a586cf829f0f2009aacc", hex.EncodeToString(np1))
  218. assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000001b274a34a3bd95915fe982a0163e3e0a2f79a371b8307661341f8914e22b313e1", hex.EncodeToString(np2))
  219. }
  220. func TestGetLeafInPos(t *testing.T) {
  221. mt := newTestingMerkle(t, 140)
  222. defer mt.storage.Close()
  223. for i := 0; i < 50; i++ {
  224. leaf := newTestLeaf("iden3.io"+strconv.Itoa(i), "typespec"+strconv.Itoa(i), []byte("c"+strconv.Itoa(i)))
  225. mt.Add(leaf)
  226. }
  227. leaf1 := newTestLeaf("iden3.io_x", "typespec_x", []byte("cx"))
  228. assert.Nil(t, mt.Add(leaf1))
  229. leaf := parseTestLeafBytes(leaf1.Bytes())
  230. leafInPosBytes, err := mt.GetValueInPos(leaf.hi())
  231. assert.Nil(t, err)
  232. assert.Equal(t, leaf1.Bytes(), leafInPosBytes)
  233. // empty value in position
  234. leaf2 := newTestLeaf("iden3.io_y", "typespec_y", []byte("cy"))
  235. leafInPosBytes, err = mt.GetValueInPos(leaf2.hi())
  236. assert.Nil(t, err)
  237. assert.Equal(t, EmptyNodeValue[:], leafInPosBytes)
  238. }
  239. type vt struct {
  240. v []byte
  241. idxlen uint32
  242. }
  243. func (v vt) IndexLength() uint32 {
  244. return v.idxlen
  245. }
  246. func (v vt) Bytes() []byte {
  247. return v.v
  248. }
  249. func TestVector4(t *testing.T) {
  250. mt := newTestingMerkle(t, 4)
  251. defer mt.storage.Close()
  252. zeros := make([]byte, 32, 32)
  253. zeros[31] = 1 // to avoid adding Empty element
  254. assert.Nil(t, mt.Add(vt{zeros, uint32(1)}))
  255. v := vt{zeros, uint32(2)}
  256. assert.Nil(t, mt.Add(v))
  257. proof, _ := mt.GenerateProof(HashBytes(v.Bytes()[:v.IndexLength()]))
  258. assert.True(t, CheckProof(mt.Root(), proof, HashBytes(v.Bytes()[:v.IndexLength()]), HashBytes(v.Bytes()), mt.NumLevels()))
  259. assert.Equal(t, 4, mt.NumLevels())
  260. assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000001", hex.EncodeToString(v.Bytes()))
  261. assert.Equal(t, "0xc1b95ffbb999a6dd7a472a610a98891ffae95cc973d1d1e21acfdd68db830b51", mt.Root().Hex())
  262. assert.Equal(t, "00000000000000000000000000000000000000000000000000000000000000023cf025e4b4fc3ebe57374bf0e0c78ceb0009bdc4466a45174d80e8f508d1a4e3", hex.EncodeToString(proof))
  263. }
  264. func TestVector140(t *testing.T) {
  265. mt := newTestingMerkle(t, 140)
  266. defer mt.storage.Close()
  267. zeros := make([]byte, 32, 32)
  268. zeros[31] = 1 // to avoid adding Empty element
  269. for i := 1; i < len(zeros)-1; i++ {
  270. v := vt{zeros, uint32(i)}
  271. assert.Nil(t, mt.Add(v))
  272. proof, err := mt.GenerateProof(HashBytes(v.Bytes()[:v.IndexLength()]))
  273. assert.Nil(t, err)
  274. assert.True(t, CheckProof(mt.Root(), proof, HashBytes(v.Bytes()[:v.IndexLength()]), HashBytes(v.Bytes()), mt.NumLevels()))
  275. if i == len(zeros)-2 {
  276. assert.Equal(t, 140, mt.NumLevels())
  277. assert.Equal(t, uint32(30), v.IndexLength())
  278. assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000001", hex.EncodeToString(v.Bytes()))
  279. assert.Equal(t, "0x35f83288adf03bfb61d8d57fab9ed092da79833b58bbdbe9579b636753494ebd", mt.Root().Hex())
  280. assert.Equal(t, "000000000000000000000000000000000000000000000000000000000000001f0d1f363115f3333197a009b6674f46bba791308af220ad71515567702b3b44a2b540c1abad0ff81386a78b77e8907a56b7268d24513928ae83497adf4ad93a55e380267ead8305202da0640c1518e144dee87717c732b738fa182c6ef458defd6baf50022b01e3222715d4fca4c198e94536101f6ac314b3d261d3aaa0684395c1db60626e01c39fe4f69418055c2ebd70e0c07b6d9db5c4aed0a11ed2b6a773", hex.EncodeToString(proof))
  281. }
  282. }
  283. }