| // Copyright 2020 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "securegcm/java_util.h" |
| |
| #include <cstring> |
| |
| namespace securegcm { |
| namespace java_util { |
| |
| namespace { |
| |
| // Returns the lower 32-bits of a int64_t |value| as an int32_t. |
| int32_t Lower32Bits(int64_t value) { |
| const uint32_t lower_bits = static_cast<uint32_t>(value & 0xFFFFFFFF); |
| int32_t return_value; |
| std::memcpy(&return_value, &lower_bits, sizeof(uint32_t)); |
| return return_value; |
| } |
| |
| } // namespace |
| |
| int32_t JavaMultiply(int32_t lhs, int32_t rhs) { |
| // Multiplication guaranteed to fit in int64_t, range from [2^63, 2^63 - 1]. |
| // Minimum value is (-2^31)^2 = 2^62. |
| const int64_t result = static_cast<int64_t>(lhs) * static_cast<int64_t>(rhs); |
| return Lower32Bits(result); |
| } |
| |
| int32_t JavaAdd(int32_t lhs, int32_t rhs) { |
| const int64_t result = static_cast<int64_t>(lhs) + static_cast<int64_t>(rhs); |
| return Lower32Bits(result); |
| } |
| |
| int32_t JavaHashCode(const securemessage::ByteBuffer& byte_buffer) { |
| const string bytes = byte_buffer.String(); |
| int32_t hash_code = 1; |
| for (const int8_t byte : bytes) { |
| int32_t int_value = static_cast<int32_t>(byte); |
| // Java relies on the overflow/underflow behaviour of arithmetic operations, |
| // which is undefined in C++, so we call our own Java-compatible versions of |
| // + and * here. |
| hash_code = JavaAdd(JavaMultiply(31, hash_code), int_value); |
| } |
| return hash_code; |
| } |
| |
| } // namespace java_util |
| } // namespace securegcm |