浏览代码

GiantUInt multiplication

Nathan Fallet 4 年之前
父节点
当前提交
50dfd85dda
共有 2 个文件被更改,包括 37 次插入2 次删除
  1. 24 1
      Sources/CryptoSwift/GiantUInt.swift
  2. 13 1
      Tests/CryptoSwiftTests/GiantUIntTests.swift

+ 24 - 1
Sources/CryptoSwift/GiantUInt.swift

@@ -48,6 +48,29 @@ struct GiantUInt: Equatable {
     return GiantUInt(newBytes)
   }
   
-  
+  static func * (rhs: GiantUInt, lhs: GiantUInt) -> GiantUInt {
+    var offset = 0
+    var sum = [GiantUInt]()
+    
+    for rbyte in rhs.bytes {
+      var bytes = [UInt8](repeating: 0, count: offset)
+      var r: UInt8 = 0
+      
+      for lbyte in lhs.bytes {
+        let res = UInt16(rbyte) * UInt16(lbyte) + UInt16(r)
+        r = UInt8(res >> 8)
+        bytes.append(UInt8(res & 0xff))
+      }
+      
+      if r != 0 {
+        bytes.append(r)
+      }
+      
+      sum.append(GiantUInt(bytes))
+      offset += 1
+    }
+    
+    return sum.reduce(GiantUInt([]), +)
+  }
   
 }

+ 13 - 1
Tests/CryptoSwiftTests/GiantUIntTests.swift

@@ -30,12 +30,24 @@ final class GiantUIntTests: XCTestCase {
     XCTAssertEqual(c, GiantUInt([144, 145, 1]), "addition with double retenue failed")
   }
   
+  func testMultiplication() {
+    let a = GiantUInt([2]) * GiantUInt([2])
+    XCTAssertEqual(a, GiantUInt([4]), "simple multiplication failed")
+    
+    let b = GiantUInt([200]) * GiantUInt([200])
+    XCTAssertEqual(b, GiantUInt([64, 156]), "multiplication with retenue failed")
+    
+    let c = GiantUInt([200, 200]) * GiantUInt([200, 200])
+    XCTAssertEqual(c, GiantUInt([64, 28, 121, 157]), "multiplication with double retenue failed")
+  }
+  
 }
 
 extension GiantUIntTests {
   static func allTests() -> [(String, (GiantUIntTests) -> () -> Void)] {
     let tests = [
-      ("testAddition", testAddition)
+      ("testAddition", testAddition),
+      ("testMultiplication", testMultiplication)
     ]
 
     return tests