Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/PyNaCl-1.6.0.dev1-py3.8-linux-x86_64.egg/nacl/bindings/utils.py: 15%

54 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-06 06:06 +0000

1# Copyright 2013-2017 Donald Stufft and individual contributors 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15import nacl.exceptions as exc 

16from nacl._sodium import ffi, lib 

17from nacl.exceptions import ensure 

18 

19 

20def sodium_memcmp(inp1: bytes, inp2: bytes) -> bool: 

21 """ 

22 Compare contents of two memory regions in constant time 

23 """ 

24 ensure(isinstance(inp1, bytes), raising=exc.TypeError) 

25 ensure(isinstance(inp2, bytes), raising=exc.TypeError) 

26 

27 ln = max(len(inp1), len(inp2)) 

28 

29 buf1 = ffi.new("char []", ln) 

30 buf2 = ffi.new("char []", ln) 

31 

32 ffi.memmove(buf1, inp1, len(inp1)) 

33 ffi.memmove(buf2, inp2, len(inp2)) 

34 

35 eqL = len(inp1) == len(inp2) 

36 eqC = lib.sodium_memcmp(buf1, buf2, ln) == 0 

37 

38 return eqL and eqC 

39 

40 

41def sodium_pad(s: bytes, blocksize: int) -> bytes: 

42 """ 

43 Pad the input bytearray ``s`` to a multiple of ``blocksize`` 

44 using the ISO/IEC 7816-4 algorithm 

45 

46 :param s: input bytes string 

47 :type s: bytes 

48 :param blocksize: 

49 :type blocksize: int 

50 :return: padded string 

51 :rtype: bytes 

52 """ 

53 ensure(isinstance(s, bytes), raising=exc.TypeError) 

54 ensure(isinstance(blocksize, int), raising=exc.TypeError) 

55 if blocksize <= 0: 

56 raise exc.ValueError 

57 s_len = len(s) 

58 m_len = s_len + blocksize 

59 buf = ffi.new("unsigned char []", m_len) 

60 p_len = ffi.new("size_t []", 1) 

61 ffi.memmove(buf, s, s_len) 

62 rc = lib.sodium_pad(p_len, buf, s_len, blocksize, m_len) 

63 ensure(rc == 0, "Padding failure", raising=exc.CryptoError) 

64 return ffi.buffer(buf, p_len[0])[:] 

65 

66 

67def sodium_unpad(s: bytes, blocksize: int) -> bytes: 

68 """ 

69 Remove ISO/IEC 7816-4 padding from the input byte array ``s`` 

70 

71 :param s: input bytes string 

72 :type s: bytes 

73 :param blocksize: 

74 :type blocksize: int 

75 :return: unpadded string 

76 :rtype: bytes 

77 """ 

78 ensure(isinstance(s, bytes), raising=exc.TypeError) 

79 ensure(isinstance(blocksize, int), raising=exc.TypeError) 

80 s_len = len(s) 

81 u_len = ffi.new("size_t []", 1) 

82 rc = lib.sodium_unpad(u_len, s, s_len, blocksize) 

83 if rc != 0: 

84 raise exc.CryptoError("Unpadding failure") 

85 return s[: u_len[0]] 

86 

87 

88def sodium_increment(inp: bytes) -> bytes: 

89 """ 

90 Increment the value of a byte-sequence interpreted 

91 as the little-endian representation of a unsigned big integer. 

92 

93 :param inp: input bytes buffer 

94 :type inp: bytes 

95 :return: a byte-sequence representing, as a little-endian 

96 unsigned big integer, the value ``to_int(inp)`` 

97 incremented by one. 

98 :rtype: bytes 

99 

100 """ 

101 ensure(isinstance(inp, bytes), raising=exc.TypeError) 

102 

103 ln = len(inp) 

104 buf = ffi.new("unsigned char []", ln) 

105 

106 ffi.memmove(buf, inp, ln) 

107 

108 lib.sodium_increment(buf, ln) 

109 

110 return ffi.buffer(buf, ln)[:] 

111 

112 

113def sodium_add(a: bytes, b: bytes) -> bytes: 

114 """ 

115 Given a couple of *same-sized* byte sequences, interpreted as the 

116 little-endian representation of two unsigned integers, compute 

117 the modular addition of the represented values, in constant time for 

118 a given common length of the byte sequences. 

119 

120 :param a: input bytes buffer 

121 :type a: bytes 

122 :param b: input bytes buffer 

123 :type b: bytes 

124 :return: a byte-sequence representing, as a little-endian big integer, 

125 the integer value of ``(to_int(a) + to_int(b)) mod 2^(8*len(a))`` 

126 :rtype: bytes 

127 """ 

128 ensure(isinstance(a, bytes), raising=exc.TypeError) 

129 ensure(isinstance(b, bytes), raising=exc.TypeError) 

130 ln = len(a) 

131 ensure(len(b) == ln, raising=exc.TypeError) 

132 

133 buf_a = ffi.new("unsigned char []", ln) 

134 buf_b = ffi.new("unsigned char []", ln) 

135 

136 ffi.memmove(buf_a, a, ln) 

137 ffi.memmove(buf_b, b, ln) 

138 

139 lib.sodium_add(buf_a, buf_b, ln) 

140 

141 return ffi.buffer(buf_a, ln)[:]